企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### JS的执行阶段 解释器解释完语法规则后,就开始执行,然后整个执行流程中大致包含以下概念: - 执行上下文,执行堆栈概念(如全局上下文,当前活动上下文) - VO(变量对象)和 AO(活动对象) - 作用域链 - this 机制等 **执行上下文简单解释** - JS 有 `执行上下文` - 浏览器首次载入脚本,它将创建 `全局执行上下文`,并压入执行栈栈顶(不可被弹出) - 然后每进入其它作用域就创建对应的执行上下文并把它压入执行栈的顶部 - 一旦对应的上下文执行完毕,就从栈顶弹出,并将上下文控制权交给当前的栈。 - 这样依次执行(最终都会回到全局执行上下文) 譬如,如果程序执行完毕,被弹出执行栈,然后有没有被引用(没有形成闭包),那么这个函数中用到的内存就会被垃圾处理器自动回收 ![img](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/date/2018-04-27/js_engine_context_stack.png) 然后执行上下文与VO,作用域链,this的关系是: 每一个执行上下文,都有三个重要属性: - 变量对象 (`Variable object,VO`) - 作用域链 (`Scope chain`) - `this` ![img](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/date/2018-04-27/js_engine_context.png) **VO 与 AO** VO 是执行上下文的属性(抽象概念),但是**只有全局上下文的变量对象允许通过VO的属性名称来间接访问(因为在全局上下文里,全局对象自身就是变量对象)** AO(`activation object`),当函数被调用者激活,AO就被创建了 可以理解为: - 在函数上下文中:`VO === AO` - 在全局上下文中:`VO === this === global` 总的来说,VO中会存放一些变量信息(如声明的变量,函数,`arguments`参数等等) **作用域链** 它是执行上下文中的一个属性,原理和原型链很相似,作用很重要。 譬如流程简述: ``` 在函数上下文中,查找一个变量foo 如果函数的VO中找到了,就直接使用 否则去它的父级作用域链中(__parent__)找 如果父级中没找到,继续往上找 直到全局上下文中也没找到就报错 ``` ![img](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/date/2018-04-27/js_engine_scopechain.png) **this指针** 这也是JS的核心知识之一,特别注意:**this是执行上下文环境的一个属性,而不是某个变量对象的属性** 因此: - this 是没有一个类似搜寻变量的过程 - 当代码中使用了this,这个 this的值就直接从执行的上下文中获取了,而不会从作用域链中搜寻 - this的值只取决中进入上下文时的情况 所以经典的例子: ```js var baz = 200; var bar = { baz: 100, foo: function() { console.log(this.baz); } }; var foo = bar.foo; // 进入环境:global foo(); // 200,严格模式中会报错,Cannot read property 'baz' of undefined // 进入环境:global bar bar.foo(); // 100 ``` 就要明白了上面 this 的介绍,上述例子很好理解