从定义到
执行Javascript,JS引擎在实现层做很多初始化,所以在
学习JS引擎的
工作机制,我们需要引入一些相关概念:执行环境,全局栈对象,执行环境,可变对象,主动对象、范围和
作用域链,概念是
核心部件JS引擎工作。
本文的目的不是孤立地解释每一个概念,而是通过一个简单的演示来分析JS引擎从定义到执行的每个细节,以及这些概念在其中的作用。
变量x = 1;定义全局变量x
函数A(y){
变量x = 2;定义一个局部变量x
函数B(z)定义内部B函数
console.log(X + Y + Z);
}
返回;返回函数B
}
var A =(1);
C(1);执行
功能B
演示是一个闭包,执行结果是4。接下来,我们将分析JS引擎的工作机制,分为三个阶段:全局初始化、执行函数A和执行函数B。
首先,全局初始化
当js引擎
输入一段
可执行代码时,它需要完成以下三个初始化
任务:
首先,
创建一个全局对象(全局对象),该对象只有一个对象的一部分。它的
性能可以无处不在,它的存在是伴随着
应用程序的整个生命周期。当一个全局对象创建时,常用的JS对象,如数学,字符串,
日期和
文件,作为他们的
属性。因为全局对象不能用
名字直接访问,有另一个属性窗口,点窗口本身,这样我们就可以通过窗口访问全局对象,全局对象的总体结构进行伪代码如下:
创建全局对象
无功globalobject = { {
数学:{ },
字符串:{ },
日期:{ },
文档:{、}、DOM / DOM
操作 …
窗口:这个窗口属性指向他们自己
}
然后,js引擎需要构建一个执行环境堆栈(执行上下文堆栈)。同时,全局执行环境(执行上下文)EC也创造,和全局执行环境EC推入执行环境堆栈。对环境的堆栈执行的功能是确保程序能以
正确的
顺序执行。在Javascript,每个函数都有它自己的执行环境。执行函数时,函数的执行环境将推到栈顶的执行环境和执行力。当函数完成,其执行环境是从堆栈的顶部去掉,并执行返回到以前的执行环境。我们用伪代码来
模拟栈的执行与电子商务的关系:
Var ECStack = {}; / /定义一个执行环境叠加,类似于数组
创建一个执行
空间,
/ / ECMA-262规范不做电子商务的数据结构有一个清晰的定义,你可以了解一个空间分配
内存。
ECStack.push(EC); / /输入功能,按执行环境
ECStack.pop(EC); / /返回功能,
删除执行环境
最后,全局变量引擎也会创建一个JS对象与电子商务相关的(可变对象VO),和VO指向全局对象,对象不仅包括全局对象的原始属性,也包含在全局变量x的定义和功能,同时,在一个函数的定义,添加一个内部属性的范围,范围和VO。当每个函数的定义、范围的属性,它是相关的,和范围总是指向环境中的函数定义,ecstack结构在这个时间如下:
ecstack = { / /执行环境栈
EC(g)=全局执行环境
VO(g):定义变量对象
包含原文…全局对象属性
x=1;定义变量x
(a =函数){…};函数a
一个范围定义,并赋给VO本身
}
}
};
两。执行功能
当执行进入A(1)时,js引擎需要执行以下工作:
首先,js引擎创建函数A的执行环境EC,然后EC推入执行环境栈的顶部并得到执行。此时,执行环境堆栈中有两个执行环境,即全局执行环境和函数执行环境。一个执行环境是在堆栈的顶部,与全局执行环境是在栈底。然后,作用域链中创建一个函数(范围、链)在Javascript,每个执行环境都有它自己的作用域链,用于标识解析,当执行环境的创建,它的作用域链被初始化为
目标函数的
运行范围包含。
然后,活动对象的JS引擎会创建一个当前的功能(
激活对象AO),活动对象只有在变量对象中扮演一个角色,在一个不同的名称功能(你可以认为可变对象是一个广义的概念,和移动的物体是它的一个分支),AO包含函数
参数争论的对象,这个对象,局部变量和内部函数的定义,然后敖将被推入作用域链的顶端。注意,在B的函数的定义,JS引擎也将添加一个范围属性B、范围和功能B环境,AO活动对象定义函数B环境是,AO位于前面的列表,列表中有一个
连接的尾部特征特色,因此B的功能范围,作用域链让的坐在ecstack结构看这一点。
ecstack = { / /执行环境栈
EC(a)= a/a a的执行环境
{ }:VO(g)、是全局变量对象
AO(a):创建函数对象
y:1,
x:2,x 定义局部变量
(b:函数){…},函数B
B { { } } =这个范围; / /这是AO,AO在scopechain顶部,所以B { { } }点范围的整个作用域链
参数:{我们通常在参数的函数中访问AO是AO参数
这个:窗口/这个函数到调用者对象窗口
},
scopechain: / /列表初始化为{ } } {范围,然后把顶部的AO到作用域链,然后一个作用域链:AO(一)-> VO(G)
},
EC(g)=全局执行环境
VO(g):创建全局变量对象
包含原文…全局对象属性
x=1;定义变量x
(a =函数){…};函数a
{此} =;定义范围;
}
}
};
三。执行功能B
函数A被执行后,它返回B的引用并将变量赋给变量C。C(1)的执行相当于B(1)的执行,js引擎需要做以下工作:
首先,以及上面的函数B执行环境EC被创建,然后统推到栈顶的执行环境并得到执行。在这个时候,有在执行环境堆栈的执行环境,即全局执行环境和执行环境功能B. B执行环境是在堆栈的顶部,与全局执行环境是在栈底。(注:当函数返回时,一个执行环境将被删除从栈,只留下全局执行环境)。然后,创建和初始化函数B的作用域链中B的功能,即对象的范围,作用域链中含有A.最后,活动对象AO功能B创建,和Z参数,参数对象,和这个对象的B作为AO的性质。在这一点上,ECStack将把这:
ecstack = { / /执行环境栈
EC(b)=创建一个B执行环境,并在范围链的顶部
{ }:AO(a)、作用域链到a、AO(a)- VO(g)的函数中
var(b)活动对象
z:1,
参数:{ },
本:窗口
}
scopechain: / /列表初始化B { { } }范围,然后AO(B)加入列表标题,然后B范围链:AO(B)-> AO(一)-武(G)
},
EC(a),堆栈的执行环境已从堆栈顶部删除,
EC(g)=全局执行环境
VO:全局对象
包含原文…全局对象属性
x=1;定义变量x
(a =函数){…};函数a
{此} =;定义范围;
}
}
};
当函数B X + Y + Z是执行,一个需要
解决的X,Y,Z三标识符解析过程符合变量查找规则:如果属性存在,找他们自己的活动对象是否存在,然后停止
搜索并返回;如果没有,继续沿着使用范围从为链上找,直到你找到它,如果变量不在作用域链,
发现返回未定义。从以上分析,我们可以看到,函数B的功能域链是这样的:
AO(b)- AO(A)- VO(G)
因此,变量x将在AO(A)中找到,而不是x在VO(g)中。y也会出现在AO(a)中,变量Z在它自己的AO(z)中被发现,所以执行结果是:2 + 1 + 1 = 4。
一个简单的总结
经了解,JS引擎的工作机制,我们不能仅仅停留在概念的理解水平,但把它作为
优化和改善我们的工作实际代码的基本
工具,提高执行效率和产生的实际价值,这才是我们真正的目标。以变量查找机制,如果你的代码是深套,每提到一个全局变量,JS引擎查找作用域链,如在作用域链在窗口和文档对象的底部有问题,所以我们将集中在这个问题上做了大量的优化工作。当然,还有其他方面的优化,这里没有提到,这篇文章只是作为一些东西!
以上是本文的全部内容,希望能对大家有所帮助。