You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(functionfoo(){(functionbar(){throw'Exit from bar and foo contexts';})();})();
Eval代码
在这种情况下,存在一个调用上下文的概念,比如调用eval函数时的上下文
eval函数中所做的操作(如变量或函数定义)影响整个调用上下文:
// influence global contexteval('var x = 10');(functionfoo(){// and here, variable "y" is// created in the local context// of "foo" functioneval('var y = 20');})();alert(x);// 10alert(y);// "y" is not defined
介绍
本文中,我们将分析ECMAScript的执行上下文以及相关的可执行代码的类型
先举个栗子🌰,为什么a和b表现大不相同,当引用一个函数或者变量时,解释器是如何以及从哪里找到它们的呢
定义
每当控制器执行到ECMAScript可执行代码时,控制器就进入执行上下文
该标准并没有对EC的结构和种类做出准确的定义
逻辑上,一系列活动的执行上下文形成一个堆栈,这个堆栈的底部总是一个全局上下文,顶部是当前活动的执行上下文,在不同的执行上下文间切换时(进入和退出各种EC),堆栈被修改(通过压栈或者退栈)
可执行代码的类型
可执行代码类型与执行上下文是相关的,说到代码类型,就是指执行上下文
例如,我们将执行上下文的堆栈定义为一个数组:
每次控制器进入一个函数(即使该函数被递归调用或作为构造函数),都会发生压栈的操作,内置eval函数也不例外
全局代码
这种类型的代码在程序级中处理,即加载外部.js文件或本地内联代码(在
<script></script>
标签内),全局代码不包含函数体内的任何代码在初始化(程序启动)时,ECStack如下:
函数代码
控制器进入函数代码(各类函数)时,会有新的元素会被压栈到ECStack,要注意的是,实体函数代码并不包括内部函数的代码
例如,我们来看看递归调用一次的函数:
之后,ECStack就被修改成:
每次函数返回,退出当前活动的执行上下文时,ECStack就会被执行对应的退栈操作,先进后出,和传统的栈实现一致,这些代码执行完之后,ECStack中就只剩下一个执行上下文(globalContext),直到程序结束
当抛出未捕获的异常时也可能会退出一个或多个执行上下文:
Eval代码
在这种情况下,存在一个调用上下文的概念,比如调用eval函数时的上下文
eval函数中所做的操作(如变量或函数定义)影响整个调用上下文:
对于上面的示例,ECStack被修改为:
在旧版SpiderMonkey(版本1.7及以前)实现中,可以将调用上下文作为eval函数的第二个参数传递,因此,如果上下文仍然存在,就有可能影响私有变量:
引用
ECMA-262-3 in detail. Chapter 1. Execution Contexts.
The text was updated successfully, but these errors were encountered: