搞清楚js环境的执行栈、环境栈和变量提升,对于如何组织js代码,非常关键。
1.执行栈和环境栈所有的 JS 代码在运行时都是在执行上下文中进行的。执行上下文是一个抽象的概念,JS 中有三种执行上下文: 全局执行上下文,默认的,在浏览器中是 window 对象,并且 this 在非严格模式下指向它。 函数执行上下文,JS 的函数每当被调用时会创建一个上下文。 Eval 执行上下文,eval 函数会产生自己的上下文,这里不讨论。
1.1 创建环节(函数被调用,但未未被执行)会执行三件事情。 创建变量对象,首先初始化函数的arguments对象,提升函数声明和变量声明,从近到远查找函数运行所需要的变量。 创建作用域链,作用域就是一个独立的地盘,让变量不会相互干扰,当前作用域没有定义的变量,这成为自由变量。自由变量会向上一直寻找,要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”,如果最终没有就为undefined。这种层层之间就构成了作用域链。 确定this指向,this、apply、call的指向。
1.2 JavaScript引擎是单线程执行,所有代码都是排队执行。 1.一开始执行的是全局代码,首先创建全局的执行上下文,然后将该执行上下文压入执行栈中。 2.每当执行一个函数,就会创建该函数的执行上下文,然后将其压入执行栈的顶部,函数执行完成后,执行上下文从底部退出,等待垃圾回收。 3.游览器js总是访问执行栈顶层的执行上下文。 4.全局上下文只有唯一的一个,它在浏览器关闭时出栈
几个关键点:单线程、同步执行、1个Global context、无限制的函数context、每个函数调用都会创建新的execution context,即使是自己调用自己。
1.3 解释器执行代码的伪综述。 1.找到调用函数的代码。 2.在执行函数代码之前,创建execution context。 3.进入创建阶段: 初始化Scope Chain 创建variable object 创建实参对象(arguments object),检查context的形参(parameters),初始化参数的名称和参数值并且创建一份引用的拷贝。 扫描context中的函数声明:为每一个函数在varible object上创建一个属性,属性名就是函数名,含有一个指向内存中函数的引用指针。如果函数名已经存在了,这个引用指针的值将会被重写。 扫描context中的变量申明:为每一个变量在variable object上创建一个属性,属性名就是变量名并;且将变量的值初始化为undefined。如果变量名在variable object中已经存在,那就什么都不会发生,并且继续扫描。 确定context中 "this"的值。 4.激活 / 代码执行阶段: 运行 / 解释context中的函数代码,并且根据代码一行一行的执行,为变量赋值。
2.变量提升解释变量和函数的声明在它们的作用域中被提前。但是,没有从细节上解释为什么会发什么这种现象。通过了解解释器如何创建activation object,就很容易知道这种现象发生的原因了。看下面这个例子:
(function() {
console.log(typeof foo); // function pointer
console.log(typeof bar); // undefined
var foo = 'hello',
bar = function() {
return 'world';
};
function foo() {
return 'hello';
}
}());
在foo声明之前,为什么我们可以访问它? 如果我们来跟踪creation stage, 我们知道在代码执行阶段之前,变量已经被创建了。因此在函数流开始执行之前,foo已经在activation object中被定义了。 foo 被声明了两次,为什么 foo 最后显示出来是一个function,并不是undefined或者是string?尽管 foo 被声明了两次,我们知道,在创建阶段,函数的创建是在变量之前的,并且如果属性名在activation object中已经存在的话,我们是会简单的跳过这个声明的。 因此,对 function foo()的引用在activation object上先被创建了,当解释器到达 var foo 时,我们会发现属性名 foo 已经存在了,因此代码什么都不会做,继续向下执行。
为什么 bar 是undefined? bar实际上是一个变量,并且被赋值了一个函数的引用。我们知道变量是在创建阶段被创建的,但是它们会被初始化为undefined,所以bar是undefined。
3.闭包闭包是指有权访问另一个函数作用域中的变量的函数。
4.作者答疑合理的脚本代码可以有效的提高工作效率,减少重复劳动。
提示: 作者知了-联系方式1 提示: 作者知了-联系方式2