木灵鱼儿
阅读:348
执行上下文
什么是执行上下文
JavaScript引擎在执行代码阶段时,通常是调用函数的时候,就会先做一些准备工作,这个准备工作被称为执行上下文,简称EC,或者也可以叫做执行环境。
执行上下文也是有不同的,有三个类型:
- 全局执行上下文:最基础的执行上下文,一个程序也只会存在一个全局执行上下文,全局上下文会生成一个全局对象,这个对象就是window,并且会将该上下文的中this绑定到该全局对象上。
- 函数执行上下文:当函数被调用时都是产生一个新的上下文对象,不管函数是否是重复调用
- Eval函数执行上下文:执行在
eval
函数内部的代码也会有它属于自己的执行上下文
而this是由上下文中提供的,我们可以将上下文理解为一个object,这样可以方便认知它。
上下文在创建的时候会创建两个环境:
- 词法环境 LexicalEnvironment
- 变量环境 VariableEnvironment
词法环境是比较新的一个环境,用于存放let、const等等一些变量和对应的值,其中就有this
属性。
变量环境是ES6用于区分var声明而提供的环境,里面存放var声明的变量。
let a = 10;
function foo() {
let b = 20;
var d = 40;
console.log(a, b);
}
foo();
这段代码会生成以下上下文环境(伪代码):
//全局执行上下文
GlobalExecutionContext = {
//词法环境
LexicalEnvironment: {
EnvironmentRecord: {
type: 'object',
this: <globalObject>,
a: <uninitialized>,
foo: <function>
},
outer: <null>
},
//变量环境
VariableEnvironment: {
EnvironmentRecord: {
type: 'object',
this: <globalObject>
},
outer: null
},
}
//函数执行上下文
FunctionExecutionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
type: 'declarative',
this: <globalObject>, // 严格模式下为undefined
arguments: {length: 0},
b: <uninitialized>,
},
outer: <GlobalLexicalEnvironment>
},
VariableEnvironment: {
EnvironmentRecord: {
type: 'declarative',
this: <globalObject> // 严格模式下为undefined
d: undefined,
},
outer: <GlobalLexicalEnvironment>
},
}
使用const和let声明的变量在LexicalEnvironment
词法环境中,它的值一开始是uninitialized
,所以虽然在运行时这个变量就存在于环境中了,但是它是一个未初始化的值,所以在没有执行到对应的声明时,提前读取它会触发ReferenceError
报错,这个特性又称之为暂时性死区,而var声明在变量环境中是undefined,所以即时没有被赋值,也是可以正常获取到值,并不会报错。
this会在上下文环境中定义,在下一篇文章,我会讲述定义的规则,这里就不详细说明了。
上下文环境是在运行时创建,在代码使用完就会销毁(除了全局上下文),它就是一个内存中的栈空间,代码在运行时开辟出来,使用完就销毁。虽然这个和作用域很相像,但是不是一个东西,而且是不同生命周期内的产物。
反倒是引擎在创建上下文时,会通过作用域查询对应的变量,然后将需要的内容丢入空间内使用。
其中outer
是用于链接作用域的,本人在这块也很模糊,这个作用域个人估计是链的上下文的词法环境和变量环境,因为值只有在运行时才能确定啊。而闭包也是通过outer
查找到外部变量。
旧的知识
现在百度到的文章,很大一部分都会讲什么AO、VO啥的,其实这个知识是ES3时代的知识,其实没必要去深入学习,但是还是需要了解一下,免得被弄的眼花缭乱。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。
相关推荐
关于this
为什么会有thisthis在JavaScript中是一个非常复制的机制,它的存在其实是为了能让我们更好的复用代码,this提供了一种更优雅的方式来隐式“传递”一个对象引用,因此可以将API设计的更加简洁且易于复用。我们举个例子:new一个构造函数,我们可以得到一个新的实例对象,这个对象会继承原型,此时,如果没有this,如何在原型方法里去访问你的新的实例对象,以及获取属性这些操作。显然是不太好做的,难道每次都把自身作为参数传递给prototype上的方法吗?显然这非常不方便,如果使用了this,this会指向这个新的实例对象,那么我们在书写代码是就会更加方便了,复用也更加简单。这个thi...
vue项目里使用Object.assign的一个小技巧
当我们请求一个api的时候,他返回的数据可能会有很多,这些数据可能需要分别拆分存放在data预设的变量中。这就导致我们可能要写好几个赋值操作this.xxx = xxx; this.xx = xxx; this.xx = xxx;我们可能会重复很多次上面这种操作,是不是有点麻烦。为此,我们可以利用Object.assign来达到我们的偷懒效果Object.assign(this,{xx:xxx},{xxx:xxx});使用这种方式,我们的vue可以检测到动态改变的值,也就是说watch监听是可以触发的。且效果和你写多个this.xxx=xxx是一样的。感觉这个方法妙啊,所以分享出来,当然...
什么是上下文节点???
学html+css的时候有在书上看到过上下文节点,但是也没详细说明,看视频的时候也有人说过,但是也是一笔带过,也没在意,今天学XPath的时候就有关于上下文节点有一个说明,但是只说了一点,没啥详细,所以自己百度了下,如下:代码:<html> <body> <a id = '1'>文本节点1</a> <a id = '2'>文本节点2</a> <a id = '3'>文本节点3</a> </body> </html> ...