JavaScript-作用域链

来源:互联网 发布:手机黄金看盘软件 编辑:程序博客网 时间:2024/05/29 06:52

我们说每一个函数都是Function对象的一个实例,所有他有一些不能通过编程访问,而只能对JavaScript引擎开放的内部属性,其中一个就是[[Scope]]属性,他指向了一个函数的作用域链,而作用域链是一个类似链表的存在,每一个节点指向的都是一个具体的活动对象,这些活动对象中以“键值对”的形式存储了可以被访问的数据对象。
1.通过作用域链解析标识符
前面我们说js词法作用域的时候说过当函数遇到当前函数没有定义的变量的时候,会从词法意义上的上层父级中寻找该变量。现在,我们用作用域链来解释一下,便是全局执行上下文中存储了全局变量,函数执行上下文中存储了函数定义的只有函数作用域的变量。而函数的scope属性指向的作用域链便连接了全局上下文和函数执行上下文,所以函数运行时可以通过作用域链来访问全局对象的属性,这也是执行上下文被称作执行环境的原因,此外需要注意的是,正式因为作用域链的原因,当我们访问底层作用域的属性时,效率便会降低。

var value = 1;function foo() {    console.log(value);}function bar() {    var value = 2;    foo();}bar();//1

我们解释一下上面的代码,其实首先会有一个global的全局对象,我们可以通过window属性来访问,其次是一个bar()的活动对象,最后是foo()的活动对象,代码运行时,先将global对象压入执行上下文栈,然后压入bar()对象的执行上下文,因为bar()中引用了foo(),所以运行时将foo()执行上下文压入栈中,然而需要注意的是,对于执行上下文是三层的,而对于作用域链只有两层,这是根据词法决定的。bar()的执行上下文只是有对于foo这个函数对象的引用罢了。

2.活动对象的创建过程
活动对象是每次函数运行时都会创建的对象,因为会需要根据传入的参数初始化活动对象,然后便是对于函数内部的变量声明提前和函数声明提前。
而后根据具体的函数执行代码,函数的活动对象中的变量可能会被改变或复制。

原创粉丝点击