作用域和作用域精解
变量的作用域分为全局作用域和局部作用域,
全局作用域:即对任何内部函数来说,全局作用域的变量都是可以访问的。
局部作用域:只在自己函数内部片段可以访问,外部函数是无法访问的。
接下来看一段代码:
你感觉应该是输出 outer1 和 outer2 ,实际不是
至于为什么,这是因为对于JavaScript来说,变量只要在函数内部声明了,不管在那个位置,会自动处理成提前声明,但是赋值操作还是在原位置,也就是说上面的代码其实是这样子的:
还有一点就是对于函数内部声明的变量,一定要记得加上var ,不然其实你就相当于声明了一个全局变量
对于C或者C++来说,作用域是块级作用域,即处在某一个作用域的变量只能在其当前函数片段下起作用,脱离了当前函数片段则会报错
作用域链:用链式查找,查看那些数据能够被内部函数所访问
首先讲一下[[scope]]是什么:
每个JavaScript都是一个对象,对象中有些属性我们可以访问,但是有些是不可以的,这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个
[[scope]]指的就是我们所说的作用域,其中存储了执行期上下文的集合。
执行期上下文(AO对象):当一个函数在执行的时候,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行期上下文(AO对象),当函数执行完毕,它所产生的执行上下文被销毁。
作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。
查找变量:在哪个函数里面查找变量,就在那个函数的作用域链的顶端依次向下查找。
函数刚被定义的时候,存储的是他所存在环境的执行期上下文
当b函数被创建的时候,他所依赖的环境,就是a函数的执行环境,即b函数的执行期上下文是在a的基础上创建一个自己的AO并且插在最前面
那么现在,对于a里面的AO和b里面的AO是不是同一个呢?是的
所以对于b来说他所继承的AO只不过是a的AO的引用,两者共同维护同一组数据
现在来说说当一个函数执行完之后,他会将他原来的那个执行期上下文和自己的作用域链断开,当他再次调用的时候,就会重新申请一个执行期上下文,记得是全新的哦
记得所有a的AO都是一个,所有b的AO也都是一个
也要记得只有先执行才能才能产生这些作用域链