ECMAScriptJavascript执行流总结

给五光十色的JavaScript代码,我们有时候难免会犯错。可当好精心研究一下,哦原来是这么回事。有时候怎么会怀念怎么Javascript程序会是这般实践之为?为什么没获协调预期的答案为?自己到底是啦一样步想错了吗?这时候就想只要我是JS执行流我会怎么行?仔细思考这些问题,原来这中间尚蕴含在众多投机无熟悉的知识点,今天虽来总下,同时同意加深印象。
率先我们来熟悉几独名:

  • 履上下文栈(Execution Context Stack)
    各一样种植代码的施行还需借助自身之上下文。函数的各级一样涂鸦调用,都见面进入函数执行着之上下文,并且来算函数中变量等的价值。一个行上下文可以激活另一个上下文,就好比一个函数调用了任何一个函数(或者全局的左右文调用了一个大局函数),然后同重合一重合调用下去。逻辑上来说,这种实现方式是仓库,我们可以称之为上下文堆栈。
    激活其它上下文的某上下文被誉为 调用者(caller)
    。被激活的上下文被喻为被调用者(callee)
    。当一个caller激活了一个callee,那么这caller就会见搁浅其本身之执行,然后用控制权交给这callee.
    于是这个callee被放入堆栈,称为进行着之上下文[running/active
    execution context].
    当以此callee的上下文结束后,会把控制权再次提交她的caller,然后caller会在刚顿的地方继续执行。在此caller结束后,会延续接触其他的上下文。一个callee可以用返回(return)或者抛来好(exception)来终结自己之上下文。
    当一段子先后开始时,会先进入全局执行上下文环境[global execution
    context],
    这个邪是仓中尽底部的素。此全局程序会开始初始化,初始化生成必要的对象[objects]和函数[functions].
    以此全局上下文执行的历程被,它或许会见激活一些道(当然是就初始化过的),然后上他们的上下文环境,然后用新的元素压入堆栈。在这些初始化都得了以后,这个系统会等待一些事件(例如用户的鼠标点击等),会触发一些方,然后进一个新的上下文环境。ECMAScript运行时系统就是这般管理代码的履行。
  • 执行上下文(Execution Context)
    一个实践之上下文可以抽象的了解吧object。每一个执之上下文都产生同层层的特性(变量对象(variable
    object),this指针(this value),用意域链(scope chain) )
  • 变量对象(variable object)
    变量对象是同实施上下文相关的 数据作用域(scope of data)
    。它是跟上下文关联的不同寻常对象,用于存储于定义在上下文中的变量(variables)和函数声明(function
    declarations) 。
  • 走对象(activation object)
    当一个函数上下文中,变量对象被代表也运动目标。它含变量(variables)和函数声明(function
    declarations) 平常参数(形参)
    突出参数(arguments)对象(具有索引属性的参数映射表)。

知晓了立即几单名称后我们用几只实例来划分一下Javascript到底是什么样尽之?

if (!("a" in window)) {
    var a = 1;
}
alert(a);

这边而非加以考虑,想当的道一旦window不分包属性a,就扬言一个变量a,然后赋值为1。所以答案吧1。
但是对答案是undefined,再细致想怎么?如果您尽管是JS程序你晤面怎么运行?
详细分析:

当一段先后开始经常,会先进入全局执行上下文环境并初始化生成必要的对象,在大局执行上下文环境面临表明了变量a,根据变量声明提升,此时该上下文环境受到之变量对象VO

{a:undefined}(全局上下文中VO还包另外对象要Math,Date等对斯开不构成影响,暂无考虑)。全局上下文环境初始化好后初步施行代码,首先判断变量a是否属window对象,我们清楚变量a已经在window对象被,所以,if条件语句不见面让实践,直接执行alert,
该题可简化为:

var a;
if (!("a" in window)) {
    a = 1;
}
alert(a);  //undefined

第二题

function a(x) {
    return x * 2;
}
var a;
alert(a);

咱们懂得变量对象被以及包括函数声明也囊括变量申明,在此题中来同名的函数和变量,此时函数声明会覆盖变量声明。但切莫会见蒙已赋值的同名变量声明。所以此题中最终结果是函数
第三题

function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);

以此题中,b函数被激活会开辟一个新的内存栈并上加至实施上下文栈中,执行流进去b函数上下文,此时变量对象表示也运动目标
AO = {
x : 1,
y : 2,
a : 3,
arguments:{0:1,1:2,2:3}
}
Arguments对象是倒目标的一个性,它包括要下属性:

  1. callee — 对当前函数的援
  2. length — 真正传递的参数个数
  3. properties-indexes (字符串类型的整数)
    属性的价值就是函数的参数值(按参数列表从左到右排列)。
    properties-indexes内部因素的个数等于arguments.length.
    properties-indexes的价值与实际传递进入的参数之间是共享的。这个共享其实不是真的的共享一个内存地址,而是2只不等之内存地址,使用JavaScript引擎来管2独价值是天天平等的.

据此当代码执行到arguments[2] = 10;时a也会成10。

参考文献:

  • 深切了解JavaScript系列–汤姆大叔的博客