JS - 作用域、作用域链 - 1

306 阅读2分钟

预编译 一文中有说到:全局作用域(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