我对 JavaScript 的理解是,在脚本执行时会创建一个全局执行上下文 - 我理解为保留内存空间中的一系列键:值对 - 很像常规的 JavaScript 对象。
在函数执行时,将创建一个新的执行上下文,并可以访问“父”执行上下文。 (对我来说)这至少相当于重新初始化 JavaScript 执行环境。除了最初在全局对象中设置的键:值对不需要添加到新的执行上下文中,因为子执行上下文可以访问父级的键:值对。
例如:
function Y() {
this.prop = 4;
};
Y.prototype.doY = function() {
console.log(this.prop);
};
function X(){
this.prop = 5;
this.y = Object.create(Y.prototype);
Y.call(this.y);
};
// I can instantiate the object like so:
var x = new X();
// Which is equivalent to the following:
var x = Object.create(X.prototype);
X.call(x);
// Then I can add a function to the object that the X constructor points to via the X.prototype reference:
X.prototype.doX = function() {
console.log(this.prop)
};
// And then i can execute doX() in the context of the x object
x.doX(); // 5
x.y.doY(); // 4
执行时,doX
函数创建一个从内部引用的执行上下文x
目的。这x
对象又在全局对象中被引用。
同样,在执行时doY
函数创建一个从内部引用的执行上下文x.y
object.
在我看来,从逻辑的角度来看,函数执行创建的执行上下文基本上等同于 JavaScript 对象:
- 两者都允许变量声明对父对象/执行上下文不可见
- 两者都包含对父对象/执行上下文的某种内部引用
看起来对象和执行上下文都只是一个键:值列表,整个列表由单个(仅单个)父对象(即y
对象作为引用存在于x
执行上下文) - 或全局对象作为根父对象(x
对象作为全局执行上下文中的引用存在)。
那么问题来了:JavaScript执行上下文和JavaScript对象一样吗?如果不是,有什么区别?
这个问题:JavaScript 中的执行上下文和变量对象实际上是同一件事吗? https://stackoverflow.com/questions/28902895/are-execution-context-and-variable-object-actually-same-thing-in-javascript提到在实现方面,执行上下文和对象不是同一件事。
执行上下文继承自 Object 是否正确?或者对象/执行上下文的实现完全不相关...我可以看到的一个区别是,在创建时,执行上下文是从上到下(从词汇上讲)“处理”的,允许作者指定命令式命令 - 即指示计算机做事。但就架构而言,这种差异似乎是对象概念的延伸,而不是完全不同的东西。
在我看来,“运行 JavaScript 环境”如果存在的话,基本上就是一棵树。根节点是全局执行上下文,创建对象会将节点添加到根节点,或者(如上面 y 的情况)将节点添加到子节点。然后,子节点通过属性引用父节点,以允许将范围限定到父执行上下文。
然后就闭包而言,涉及创建(和执行)执行上下文,返回时结果对象看起来完全像常规对象,因为闭包引用的“执行上下文”永远不会再次被执行(即相同的函数) ,重新执行将创建一个新的执行上下文和闭包)。
那么,从“应用”的角度来看,是否存在这样的时刻:this
-> 即对当前执行上下文的自引用,与进行函数调用的对象不同(除了使用call
, apply
, or bind
)?即在以下情况下x.y.doY()
, 功能doY
被称为来自x.y
object.