javascript的函数作用域链

变量作用域

一个变量的作用域(scope)是程序源代码中定义这个变量的区域。
全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的。然而在函数内声明的变量只在函数体内有定义。它们是局部变量,作用域也是局部性的。函数参数也是局部变量,它们只在函数体内有定义。

在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明的一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖。

  • 全局作用域
    在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下 3 种情形拥有全局作用域。
  1. 最外层函数和在最外层函数外面定义的变量拥有全局作用域
  2. 所有末定义直接赋值的变量自动声明为拥有全局作用域
  3. 所有window对象的属性拥有全局作用域 window对象的内置属性都拥有全局作用域,例如 window.name、window.location、window.top等。
  • 局部作用域
    和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部(函数作用域)。

作用域链

在JS中:一切皆是对象, 函数也是.

JS中作用域的概念和其他语言差不多, 在每次调用一个函数的时候 ,就会进入一个函数内的作用域,当从函数返回以后,就返回调用前的作用域.

JS的语法风格和C/C++类似, 但作用域的实现却和C/C++不同,并非用“堆栈”方式,而是使用列表,具体过程如下(ECMA262中所述):

  • 任何执行上下文时刻的作用域, 都是由作用域链(scope chain)来实现.
  • 在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性.
  • 在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.

参考资料

JavaScript权威指南
Javascript作用域原理
JavaScript 作用域和作用域链

你可能感兴趣的:(javascript的函数作用域链)