JavaScript 作用域 与 作用域链
本文是参照高程(JavaScript 高级程序设计)加上一些个人的理解和总结,使用简单的小例子和一些代码片段来尽量解释清楚作用域和作用域链。(本文适用于具备一些JS基础的朋友拿来参考)
执行环境与 函数的定义和执行
执行环境定义了变量或者函数有访问其他数据的权限 。在 JavaScript 中,有一个最外层的全局执行环境,在Web浏览器中,通常我们认为就是window这个对象。
通过一个小例子来解释一下在定义函数和执行函数分别发生了哪些事情。
从这张图中,我们能看出,当我们定义了一个函数 test1 时,
1、首先在堆内存中创建了一个Function对象,然后将地址存在 test1 中;
2、自动创建一个对象,并且该对象有一个 constructor 属性指向该函数本身,最后该函数对象的prototype属性指向这个对象;
3、将包括全局对象在内的,在函数执行过程中创建的活动对象(后文解释)都存在该函数自身的内部属性[[Scope]]上。
当执行一个函数(test1)时,
1、首先会创建一个执行环境ECS及相应的作用域链;
2、然后使用arguments和函数的参数(如果有)的值来初始化函数的活动对象(Active Object)也就是上面所说的活动对象;
其中,该函数对应的作用域链是通过取出[[Scope]]的值,并且将当前函数的活动对象推入作用域链的最顶层。
以上我们简单的说了一下函数定义和执行,这样有助于我们理解作用域链以及我博客中的 闭包 和 以及 如何解释let在for循环中的特殊表现。