执行上下文(execution context)也就是红宝书(第3版)中文译本中的执行环境。
js 中有 一个全局执行上下文 ,无数函数执行上下文,无数eval执行 上下文 。
js运行时控制权会在一个个执行上下文中进行传递。
注意:
一个函数每次调用,(即使这个函数递归的调用自己)都会生成一个新的执行上下文。
执行上下文栈
所有ECMAScript程序的运行时可以用执行上下文栈来表示,栈顶是当前活跃的上下文,栈底是全局上下文。
当程序开始的时候它会进入全局执行上下文,此上下文位于栈底并且是栈中的第一个元素。然后全局代码进行一些初始化,创建需要的对象和函数。在全局上下文的执行过程中,它的可能触发其他(已经创建完成的)函数,这些函数将会进入它们自己的执行上下文,向栈中push新的元素,以此类推。
全局执行上下文和函数执行上下文的比较
在全局上下文,全局对象 (Global object) 成为当前执行上下文的变量对象。因此,全局的函数声明(区别于函数表达式)和变量声明在成为全局上下文变量对象的属性的同时也会成为全局对象的属性。
函数声明,和变量声明都会成为当前执行上下文变量对象的属性。
在函数上下文 函数的参数(形参名为属性名)和 Arguments 对象(arguments 为属性名)也将成为变量对象的属性。且变量对象的属性不可删除(即[[configurable]]=false,通过Object.getOwnPropertyDescriptor可查看)。
这也是不能删除用var声明的全局变量的原因
//用var声明全局变量的,相当于为全局上下文的变量对象添加属性 不可被删除。
var test="test";
delete test;//false
delete (window,"test")//false
//省略var声明全局变量,相当于直接给window对象添加属性 (严格模式下会报错)
test2="test2"; // 等价于window.test2="test2"可被删除。
delete test;//true
delete (window,"test2")//true
//在全局作用域用let声明的变量和用const声明的常量。
//也可被删除,但和和省略var声明不同。
//它不会成为变量对象的属性也不会直接给window对象添加属性。
//因为const与let命令的声明作用于块级作用域而不是函数作用域。
let test3="test3";
console.log(window.test3)//undefined
delete test;//true
在函数上下文 变量对象是底层实现,是抽象的不能直接访问的。当在函数代码的执行上下文时,活动对象 (Activation object) 成为当前执行上下文中的变量对象,在函数代码中申明的变量和函数成为活动对象的属性,并且函数的参数(形参名为属性名)和 Arguments 对象(arguments 为属性名)也将成为活动对象的属性。
参考自:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
网友评论