javascript上下文应该算是js这门语言基础中的基础,如果理解了它,就能比较清晰地理解js语句执行的流程,更好地分析代码。
上下文分类:
1)全局级别的上下文 2)函数级别的上下文 3)eval函数内运行的上下文
执行上下文堆栈
在《javascript高级程序设计》中,上下文被称为执行环境,其实表达的都是同一个东西。
在浏览器中,javascript引擎的工作方式是单线程的。也就是说,某一时刻只有唯一的一个事件是被激活处理的,其它的事件被放入队列中,等待被处理。
我们已经知道,当javascript代码文件被浏览器载入后,默认最先进入的是一个全局的执行上下文。当在全局上下文中调用执行一个函数时,程序流就进入该被调用函数内,此时引擎就会为该函数创建一个新的执行上下文,并且将其压入到执行上下文堆栈的顶部。浏览器总是执行当前在堆栈顶部的上下文,一旦执行完毕,该上下文就会从堆栈顶部被弹出,然后,进入其下的上下文执行代码。这样,堆栈中的上下文就会被依次执行并且弹出堆栈,直到回到全局的上下文。
执行上下文建立过程
把执行上下文看做一个对象,其下包含了以上3个属性:
executionContextObj = { variableObject: { /* 函数中的arguments对象, 参数, 内部的变量以及函数声明 */ }, scopeChain: { /* variableObject 以及所有父执行上下文中的variableObject */ }, this: {} }
执行流程:
1找到当前上下文中的调用函数的代码
2在执行被调用的函数体中的代码以前,开始创建执行上下文
3建立阶段:
建立variableObject对象
1.建立arguments对象,检查当前上下文中的参数,建立该对象下的属性以及属性值
2.检查当前上下文中的函数声明:
每找到一个函数声明,就在variableObject下面用函数名建立一个属性,属性值就是指向该函数在内存中的地址的一个引用
如果上述函数名已经存在于variableObject下,那么对应的属性值会被新的引用所覆盖。
3.检查当前上下文中的变量声明:
每找到一个变量的声明,就在variableObject下,用变量名建立一个属性,属性值为undefined。
如果该变量名已经存在于variableObject属性中,直接跳过(防止指向函数的属性的值被变量属性覆盖为undefined),原属性值不会被修改。
初始化作用域链
确定上下文中this的指向对象
4.代码执行阶段:
执行函数体中的代码,一行一行地运行代码,给variableObject中的变量属性赋值。
理解了执行上下文应该就对函数声明的作用域提升和变量声明提前有所理解了