在 预编译 一文中有说到:全局作用域(GO)、函数作用域(AO)
在AO、GO 的基础上来说明作用域、作用域链
案例一:
function test(a,b){
...
}
console.log(test)
console.log(test.name) // test
console.log(test.length) // 2
console.log(test.length) // {constructor: f}
根据案例一:可以看出 test 函数是一种对象类型,其中包括 test.name 、test.length、 test.prototype 属性,我们也可以拿到当前属性的具体值。
对象的属性分为:(这个在后面的 原型、原型链再详细说)
* 显示属性:可访问,可以获取当前属性的属性值
* 隐式属性:无法访问,JS 引擎内部固有的隐式属性
-
作用域: [[scope]]域:运行时,某一个变量、函数、对象在当前这个环境中的可访问性。
-
作用域链: Scope chain:一层一层的作用域,组合成的一个层级关系。
案例 A function test() { var a = 1 function b() {} b() } var b = 0 test()结合预编译 - 代码作用域分析 :
一、test 函数定义时作用域:
-
生成系统的[[scope]]属性,当前属性保存该函数的作用域
-
当前作用域的首位,存储当前环境下的全局执行上下文 GO
二、test 函数执行时作用域:(等同于 b 函数定义时作用域)
-
生成 test 函数的AO ,并将其排在作用域的顶端
-
根据预编译的原则,查找变量 a 和函数 b
-
test 函数执行与 b 函数 定义时的作用域 是相同的
三、b 函数执行时作用域
- 生成 b 函数的 AO,将其排在作用域的顶端
-
总结:
-
test 函数定义时的
作用域:只有 GO 作用域链也只有 GO 这一层 -
test 函数执行—— b 函数定义时:
作用域 是test 函数的AO --- 我们只分析当前 test 函数 作用域链:test()的AO -- GO -
b 函数执行:
作用域:b 函数的作用域是 b 函数的 --- 我们只分析当前 b 函数 作用域链:b()的AO --- test()的AO --- Go