作用域的初识

  • 首先从简单的方面去理解变量提升现象。在执行环境中,变量和函数声明(函数表达式不会)自动提升到最顶部,但变量赋值undefined,函数声明不会赋值undefined
var a = "outer";
function funOne() {
    console.log(a);//undefined
    var a = "inner"
}
funOne();

这个例子就能证明变量提升现象,此段代码相当于

var a = "outer";
function funOne() {
    var a;
    console.log(a);//undefined
    a = "inner"
}
funOne();

至于为什么不是输出outer,这就牵扯到一句很重要的话:作用域是在执行函数时决定的,而不是在定义函数时

  • 下面我就自己的白话解释下作用域是如何得到的。
    首先在定义函数的时候,即 function funOne() {}时,此时定义了一个作用域[[scope]],[[scope]]指向定义这个函数的环境,此例子这个环境就是全局环境,也可以把这个作用域看成一个对象,里面包含了全局环境中所有的变量,函数声明组成的键值对。

然后代码解析到funOne()这个函数时,执行这个函数,此时真正决定这个函数作用域链的时刻到了。

  • 此时将发生跟前面提到的变量提升息息相关的事情。函数执行前夕,会进入执行上下文。这在段时间期间将发生如下工作:生成一个活动对象。并且1、函数的形参赋值或undefined,2、局部变量声明但赋值undefined,3、函数声明并赋值。接下来才开始逐句解析代码,该赋值赋值,该干嘛干嘛。
  • 通过刚才的函数定义函数调用,已经生成了两个对象,两个对象分别包含变量及值的键值对。而将两个对象串起来,就变成了作用域链
  • 说白了,这个作用域链的作用是寻找变量标识名。还是在这个例子,调用函数时,进入这个函数,当解析到a时,就去作用域链中寻找a,先从活动对象找起,找不到再往上一级。

原创文章,转载请注明出处!

标签: none

添加新评论