首先我们要知道javascript语言,它是基于词法作用域的语言(简单的来说就是通过阅读包含变量在内的数行代码就能知道变量的作用域)全局变量在程序中始终是有定义的,局部变量在声明他的函数体内以及其所嵌套的函数内始终是有定义的
假如我们把局部变量换个角度来考虑,把它看成自定义实现对象的属性,那么我们就可以换个角度来解读变量的作用域。
每一段javascript代码(全局代码或函数)都有一个与之关联的作用域链(scope chain)其实这个作用域链是一个对象列表,或者是链表。 这组对象定义了这个这段代码的 “作用域中的变量”,当javascript需要查找到变量x的值的时候(这个过程叫做变量的解析) 他会从链的第一个对象开始查找,如果这个对象有一个名为x的属性,则会直接使用这个x的属性。如果第一个对象没有x属性 则会以此类推 查找下一个。若果整个作用域链上都没有这个属性,最后会抛出一个引用错误(ReferenceError)
在javascript中最顶层的代码中(注:就是不包含任何函数函数定义内的代码);作用域链由一个全局对象组成,在不包含嵌套的函数体内,作用域链上有两个对象。
第一个是定义函数参数和局部变量的对象,第二个是全局变量。需要注意的是在一个嵌套的函数内,作用域链上至少有三个对象
理解对象原型链的创建规则:
当定义一个函数时,实际上是保存了一个作用域链,当调用这个行数时,它创建一个对象来保存存储它的局部变量,并将这个对象添加到保存的那个作用域链上,同时创建一个新的更长的函数调用作用域链
对于嵌套函数来说,每次调用外部函数,内部函数都会被重新定义一遍,因为每次调用外部函数时内部函数都会被重新定义一次。因为每次调用外部函数时作用域链都是不同的。