这篇文章主要讲解了javascript执行上下文、变量对象的方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。
执行上下文 ExecutionContext
每当控制器(control)转换到ECMAScript
可执行代码时,都会创建并进入到一个可执行上下文。
一段简短的句子,却包含着丰富的内容:
js
引擎eval
代码(分别对应三种作用域)执行上下文在逻辑上组成一个堆栈。堆栈底部永远都是全局上下文(global context),堆栈顶部是当前/活动的执行上下文(activeExecutionContext)。堆栈在EC类型的变量(various kingds of EC)被推入或弹出的同时被修改。
例如,我们可以定义一个数组来模拟执行上下文堆栈:
ECStack = [ globalContext, <foo> functionContext ]
变量对象(VO)作为执行上下文的一个属性存在,它存储下列内容:
VO = { // context data (var, FD, function arguments) }
当我们声明一个变量或一个函数的时候,同时还用变量的名称和值在VO里创建了一个新的属性。
例如:
var m = 30; function test(a,b) { var c = 20 function d() {} var e = function _e() {}; } test(10)
当进入“test”函数的上下文时(传递参数10),AO如下:
AO(test) = { a: 10, b: undefined, c: undefined, d: <reference to FunctionDeclaration "d"> e: undefined };
test执行到最后时,对应此刻上下文堆栈:
ECStack = [ globalContext: { VO: { m: 30, test: } }, test functionContext: { VO: { a: 10, b: undefined, c: 20, d: <reference to FunctionDeclaration "d">, e: <reference to FunctionDeclaration "_e"> } } ]
通常,各类文章和JavaScript相关的书籍都声称:“不管是使用var关键字(在全局上下文)还是不使用var关键字(在任何地方),都可以声明一个变量”。请记住,这绝对是谣传:任何时候,变量只能通过使用var关键字才能声明。
让我们通过下面的实例看看具体的区别吧:
alert(a); // undefined alert(b); // "b" is not defined b = 10; var a = 20;
所有根源仍然是VO和它的修改阶段(进入上下文阶段和执行代码阶段):
VO = { a: undefined };
我们可以看到,因为“b”不是一个变量,所以在这个阶段根本就没有“b”,“b”将只在执行代码阶段才会出现(但是在我们这个例子里,还没有到那就已经出错了)。
让我们改变一下例子代码:
alert(a); // undefined, we know why b = 10; alert(b); // 10, created at code execution var a = 20; alert(a); // 20, modified at code execution
关于变量,还有一个重要的知识点。变量相对于简单属性来说,变量有一个特性(attribute):{DontDelete},这个特性的含义就是不同通过delete操作符直接删除变量属性。
a = 10; alert(window.a); // 10 alert(delete a); // true alert(window.a); // undefined var b = 20; alert(window.b); // 20 alert(delete b); // false alert(window.b); // still 20
2018-8-2-再看执行上下文、变量对象
看完上述内容,是不是对javascript执行上下文、变量对象的方法有进一步的了解,如果还想学习更多内容,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。