对象文本和对象文本方法的执行上下文

Execution context for object literals and object literal methods

提问人:Kumar Desai 提问时间:11/2/2023 最后编辑:jonrsharpeKumar Desai 更新时间:11/2/2023 访问量:53

问:

var objLiteral = {
    name: 'Kumar'
    myNameIs: function() {
        return this.name;
    }
};
objLiteral.name = 'Arvind';
objLiteral.myNameIs(); // returns Arvind

有人可以解释一下创建阶段和执行阶段是如何运行这段代码的吗?我了解这如何适用于 let、const、函数(全局执行上下文、函数执行上下文),但不适用于对象文字。

以下是我到目前为止的看法:

  • 创建阶段:

    1. 该对象被放置在内存中的某个位置,并且是“实时且可访问的”,并且在程序结束之前不会进行垃圾回收。objLiteral{}
    2. 为属性创建一个内存位置,其中指针返回到对象,以便在执行期间可以找到它。name
    3. 为方法创建一个内存位置,其中指针返回到对象,以便在执行期间可以找到它。myNameIs
  • 执行阶段:

    1. objLiteral.name通过跟踪先前存储的内存位置设置为值 。'Arvind'
    2. 然后调用并使用对象的内存位置和指向方法的指针/创建“函数执行上下文”。的值取自调用方法的对象。因此objLiteral.myNameIs()myNameIsthisthis==objLiteral
    3. 由于与内存相同,因此对值位置的跟踪与相同,它返回thisobjLiteralobjLiteral.name'Arvind'

何时为变量赋值,即给定对对象的引用?在创建阶段还是执行阶段?objLiteral

javascript 这个

评论

1赞 mplungjan 11/2/2023
你为什么在乎?它可能是特定于实现的
0赞 Bergi 11/2/2023
@ruan我不明白这是怎么回事
0赞 Bergi 11/2/2023
"我无法单独查看创建或执行阶段,因此我无法回答我的主要问题。有没有人知道他们知道的工具,我可以实际看到两个阶段的运行?-不。这两个阶段只是概念性的,不一定单独实施。

答:

2赞 Bergi 11/2/2023 #1

这是我到目前为止的看法。创建阶段:对象被放置在内存中的某个位置,并且是“实时且可访问的”,并且在程序结束之前不会进行垃圾回收。objLiteral{}

不,绝对不是。执行上下文以及创建阶段和执行阶段之间的分离与对象(文本)创建无关。它完全与代码执行有关,无论是在全局脚本范围内还是在函数调用中。执行上下文基本上是一个堆栈帧

对象文本中的对象在执行阶段进行分配、创建和更改,而不是在创建阶段1 期间分配、创建和更改。

因此,在您的示例中发生的情况是:

  1. 全球语境的创建阶段
    • 变量的分配和初始化objLiteralundefined
  2. 全局脚本的执行阶段
    1. 创建一个对象,创建一个字符串并将其放置在其属性中,创建一个函数(在当前作用域上具有闭包)并将其放置在其属性中,将对象分配给变量Kumar.name.myNameIsobjLiteral

    2. 查找变量中的对象,创建一个分配给对象属性的字符串objLiteralArvind.name

    3. 查找变量中的对象,查找其属性,并作为方法调用。这将创建一个新的执行上下文:objLiteral.myNameIs

      1. 函数调用的创建阶段
        • 将创建一个新范围
        • 该值设置为方法调用接收方,即对象this
        • 无需在示例中设置变量或参数声明
      2. 函数调用的执行阶段
        1. 查找 中的对象并访问其属性this.name
        2. 该值为 ed,结束函数执行return

      函数的执行上下文结束,其本地作用域不再被引用,可以进行垃圾回收,全局脚本的执行使用返回的字符串值恢复。

垃圾回收也与此无关。一旦对象不再从任何内容(变量或属性)中引用,就会对其进行垃圾回收,一旦变量(和范围)不再从任何内容(实时堆栈帧或闭包)中引用,就会对其进行垃圾回收。

1:我专门写了“from object literals”,因为有些函数对象是在创建阶段从函数声明创建的

评论

1赞 Kumar Desai 11/2/2023
美丽。我现在可以安然入睡了。我已经为这个问题苦苦挣扎了很多个晚上。非常感谢。
0赞 Kumar Desai 11/2/2023
我可能会有一些后续问题。
0赞 Bergi 11/2/2023
@KumarDesai 问问他们:-)如果这已经解决了您的问题,请考虑投票和/或接受答案
0赞 Kumar Desai 11/3/2023
我有一个关于“箭头函数方法”的问题,但后来发现,在对象字面上,箭头函数的“this”取自堆栈上前一项的执行上下文。在上面的示例中,这是 window 对象。现在一切都很好。
0赞 Bergi 11/3/2023
@KumarDesai 否,它不是从堆栈上以前的执行上下文中获取的,这取决于调用函数的时间和位置。它是在创建箭头函数时从外部作用域获取的。