菜单

JavaScript 深入的变量对象

2018年11月16日 - JavaScript

JavaScript 深入之变量对象

2017/05/13 · JavaScript
·
变量对象

原文出处: 冴羽   

都离开简书,原因参见
http://www.jianshu.com/p/0f12350a6b66。

前言

在上篇《JavaScript深入之实施上下文栈》丁提到,当JavaScript代码执行一段可实施代码(executable
code)时,会创造对应之实施上下文(execution context)。

对于每个执行上下文,都发三只举足轻重性质:

今重大出口出口创建变量对象的进程。

变量对象是跟实践上下文相关的数据作用域,存储了在内外文中定义之变量和函数声明。

以不同执行上下文下的变量对象稍有差,所以我们来聊天全局上下文下的变量对象和函数上下文下的变量对象。

就是人微言轻,但为要有友好之情态。

大局上下文

咱俩先行了解一个概念,叫全局对象。在W3C
school备受吗产生介绍:

全局对象是预定义的对象,作为 JavaScript
的大局函数和全局属性的占有位符。通过动用全局对象,可以拜有其他具有预定义的对象、函数和特性。

在顶层 JavaScript 代码中,可以为此要字 this
引用全局对象。因为全局对象是打算域链的头,这代表有非限定性的变量和函数号称都见面作该对象的特性来询问。

像,当JavaScript 代码引用 parseInt() 函数时,它引用的凡大局对象的
parseInt 属性。全局对象是企图域链的头,还意味着当顶层 JavaScript
代码中宣示的保有变量都拿成全局对象的性。

假设看的未是那个知的话语,容我再也来介绍下全局对象:

1.可以由此this引用,在客户端JavaScript中,全局对象就是Window对象。

console.log(this);

1
console.log(this);

2.全局对象是由Object构造函数实例化的一个目标。

console.log(this instanceof Object);

1
console.log(this instanceof Object);

3.预定义了一如既往堆放,嗯,一不胜堆函数和性。

// 都能立竿见影 console.log(Math.random()); console.log(this.Math.random());

1
2
3
// 都能生效
console.log(Math.random());
console.log(this.Math.random());

4.当作全局变量的宿主。

var a = 1; console.log(this.a);

1
2
var a = 1;
console.log(this.a);

5.客户端JavaScript中,全局对象来window属性指向自身。

var a = 1; console.log(window.a); this.window.b = 2; console.log(this.b)

1
2
3
4
5
var a = 1;
console.log(window.a);
 
this.window.b = 2;
console.log(this.b)

花费了一个可怜篇幅介绍全局对象,其实就算想说:

大局上下文中的变量对象就是是全局对象啊!

章可以于本人之 Github
https://github.com/mqyqingfeng/Blog
查看

函数上下文

以函数上下文中,我们所以移动对象(activation object, AO)来代表变量对象。

走对象是以上函数上下文时刻给创造的,它通过函数的arguments属性初始化。arguments属性值是Arguments对象。

实行过程

推行上下文的代码会分成两单等级进行处理:分析与执行,我们为堪称为:

  1. 上实施上下文
  2. 代码执行

登实践上下文

当进入执行上下文时,这时候还并未履行代码,

变量对象见面连:

  1. 函数的所有形参 (如果是函数上下文)
    • 鉴于名称与对应值组成的一个变量对象的性质让创造
    • 从来不实参,属性值设为undefined
  2. 函数声明
    • 由于名称与针对性应值(函数对象(function-object))组成一个变量对象的性为创造
    • 假若变量对象就在一样名称的特性,则完全替换这个特性
  3. 变量声明
    • 由名称和针对应值(undefined)组成一个变量对象的性被创造;
    • 要是变量名称以及已经宣称的形式参数或函数相同,则变量声明非会见搅乱已经有的即好像特性

举个例证:

function foo(a) { var b = 2; function c() {} var d = function() {}; b =
3; } foo(1)

1
2
3
4
5
6
7
8
9
10
function foo(a) {
  var b = 2;
  function c() {}
  var d = function() {};
 
  b = 3;
 
}
 
foo(1)

在进实施上下文后,这时候的AO是:

AO = { arguments: { 0: 1, length: 1 }, a: 1, b: undefined, c: reference
to function c(){}, d: undefined }

1
2
3
4
5
6
7
8
9
10
AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: undefined,
    c: reference to function c(){},
    d: undefined
}

代码执行

以代码执行阶段,会挨个执行代码,根据代码,修改变量对象的值

要地方的事例,当代码执行完后,这时候的AO是:

AO = { arguments: { 0: 1, length: 1 }, a: 1, b: 3, c: reference to
function c(){}, d: reference to FunctionExpression “d” }

1
2
3
4
5
6
7
8
9
10
AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: 3,
    c: reference to function c(){},
    d: reference to FunctionExpression "d"
}

及此处变量对象的创导进程尽管介绍完了,让咱简要的总我们上述所说:

  1. 全局上下文的变量对象初始化是大局对象
  2. 函数上下文的变量对象初始化只包括Arguments对象
  3. 于进入实施上下文时会叫变量对象上加形参、函数声明、变量声明等上马的属性值
  4. 在代码执行阶段,会再次修改变量对象的属性值

思考题

说到底为咱看几乎个例证:

1.第一题

function foo() { console.log(a); a = 1; } foo(); function bar() { a = 1;
console.log(a); } bar();

1
2
3
4
5
6
7
8
9
10
11
12
function foo() {
    console.log(a);
    a = 1;
}
 
foo();
 
function bar() {
    a = 1;
    console.log(a);
}
bar();

先是截会报错:Uncaught ReferenceError: a is not defined

次段会打印1。

当时是以函数中之”a”并不曾经过var关键字声明,所有未会见于存放在于AO中。

先是段子实施console的时节,AO的值是:

AO = { arguments: { length: 0 } }

1
2
3
4
5
AO = {
    arguments: {
        length: 0
    }
}

无a的价值,然后就会见暨全局去寻觅,全局也不曾,所以会报错。

当次段实施console的下,全局对象都为与了a属性,这时候就可起全局找到a值,所以会见打印1。

2.第二题

console.log(foo); function foo(){ console.log(“foo”); } var foo = 1;

1
2
3
4
5
6
7
console.log(foo);
 
function foo(){
    console.log("foo");
}
 
var foo = 1;

见面打印函数,而无是undefined。

当时是盖于进执行上下文时,首先会处理函数声明,其次会处理变量声明,如果只要变量名称以及已经宣称的款式参数或函数相同,则变量声明非会见扰乱已经有的即时仿佛性质。

深深系列

JavaScript深入系列预计写十五篇左右,旨在救助大家捋顺JavaScript底层知识,重点教学如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等困难概念,与陈它们的用法不同,这个系列还讲求通过写demo,捋过程、模拟实现,结合ES规范等艺术来上课。

具文章和demo都可于github上https://github.com/mqyqingfeng/Blog找到。如果起错或未审慎的地方,请务必与指正,十分谢谢。如果喜欢或持有启发,欢迎star,对笔者也是平栽鞭策。

本系列:

  1. JavaScirpt 深入的起原型到原型链
  2. JavaScript
    深入的词法作用域和动态作用域
  3. JavaScript 深入之推行上下文栈

    1 赞 收藏
    评论

图片 1

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图