作用域

scope

1.函数创建时,生成的一个js内部隐式属性;

2.函数存储作用域链的容器;

AO/GO

AO:函数的执行期上下文

GO:全局的执行期上下文

函数执行完成后,AO是要销毁的;AO是一个即使存储容器。

function a(){
    function b(){
        function c(){}
        c():
    }
    b();
}
a();

a定义:a.[[scope]] -> 0 : GO
a执行:a.[[scope]] -> 0 : a -> AO
                     1 : GO
b定义:b.[[scope]] -> 0 : a -> AO
                     1 : GO
b执行:b.[[scope]] -> 0 : b -> AO
                     1 : a ->AO
                     2 : GO
c定义:c.[[scope]] -> 0 : b -> AO
                     1 : a -> AO
                     2 : GO
c执行:c.[[scope]] -> 0 : c -> AO
                     1 : b -> AO
                     2 : a -> AO
                     3 : GO
c结束:c.[[scope]] -> 0 : b -> AO
                     1 : a -> AO
                     2 : GO
b结束:b.[[scope]] -> 0 : a -> AO
                     1 : GO
      c.[[scope]] 完全销毁
a结束:a.[[scope]] -> 0 : GO
      b.[[scope]] 完全销毁

JavaScript 采用的是词法作用域(静态作用域),函数的作用域在函数定义的时候就决定了,而不是函数调用的时候才决定的。

举个例子:

var value = 1;

function foo() {
    console.log(value);
}

function bar() {
    var value = 2;
    foo();
}

bar();

执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,

如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

思考:

var a = 10;
var o = {
     a:11,
     b:{
         fn:function(){
              console.log(a);
         }
     }
}
o.b.fn();

执行o.b.fn,先从 fn 函数内部查找是否有局部变量a,

如果没有,就根据书写的位置,查找o上面一层的代码,也就是 a 等于 10,所以结果会打印 10。

值得注意的是:

如果是一个函数里又嵌套一个完整的函数

里面的那个函数,其作用域必然是外层的函数

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}
checkscope()();

输出:local scope

原文地址:https://www.cnblogs.com/ssszjh/p/14355727.html