js作用域
浅层理解
1.全局作用域
1.何时创建和销毁:在浏览器打开的时候创建,在关闭浏览器的时候销毁。 2.在全局由var声明的变量,和所有的函数声明(区别于函数定义)会作为全局对象window的属性。 3.在全局作用域中会有一个window对象,代表一个浏览器窗口,由浏览器创建,可以直接调用。 4.在全局作用下的变量在任意位置都可以调用。
2.局部作用域--函数作用域(es5)---es6后有let,const就出现块级作用域
1.何时创建和销毁:在函数调用的时候创建,在函数执行完成的时候销毁。 2.内层函数可以访问外层的变量(在本层不存在的时候),而外层的不能访问内层的。 3.每调用一个函数就会创建一个全新的函数作用域,他们是相互不影响的。 4.在变量查找的时候,会在自己的局部作用域中查找,只有在局部作用域找不到了,才会向外层查找,一直到全局作用域为止。
深层理解
执行上下文:
在函数执行的前期会创建一个执行期的上下文对象ao对象(active object),这个对象是在预编译时期创建的,因为在函数调用前会有预编译时期,同理在全局代码执行的时候会创建go对象(global object);
预编译
函数的预编译
1.创建ao对象,然后将形式参数和变量声明(var的)作为自己的属性,值为undefined。 2.实际参数和形式参数相统一。 3.找函数声明,将值赋值为函数体。
全局的预编译
1.创建go对象,然后将变量声明(var的)作为自己的属性,值为undefined. 2.无函数所以无实际参数和实际参数相统一。 3.找到函数声明,将值赋为其函数体
作用域链
会被保存在一个隐式属性[[scoped]],这个是给js引擎访问的,我们用户是访问不到的,里面就存有作用域链,访问顺序由内到外逐层查找,如果查找到就停止,知道全局对象为止。