提问人:Kumar Desai 提问时间:11/2/2023 最后编辑:jonrsharpeKumar Desai 更新时间:11/2/2023 访问量:53
对象文本和对象文本方法的执行上下文
Execution context for object literals and object literal methods
问:
var objLiteral = {
name: 'Kumar'
myNameIs: function() {
return this.name;
}
};
objLiteral.name = 'Arvind';
objLiteral.myNameIs(); // returns Arvind
有人可以解释一下创建阶段和执行阶段是如何运行这段代码的吗?我了解这如何适用于 let、const、函数(全局执行上下文、函数执行上下文),但不适用于对象文字。
以下是我到目前为止的看法:
创建阶段:
- 该对象被放置在内存中的某个位置,并且是“实时且可访问的”,并且在程序结束之前不会进行垃圾回收。
objLiteral
{}
- 为属性创建一个内存位置,其中指针返回到对象,以便在执行期间可以找到它。
name
- 为方法创建一个内存位置,其中指针返回到对象,以便在执行期间可以找到它。
myNameIs
- 该对象被放置在内存中的某个位置,并且是“实时且可访问的”,并且在程序结束之前不会进行垃圾回收。
执行阶段:
objLiteral.name
通过跟踪先前存储的内存位置设置为值 。'Arvind'
- 然后调用并使用对象的内存位置和指向方法的指针/创建“函数执行上下文”。的值取自调用方法的对象。因此
objLiteral.myNameIs()
myNameIs
this
this==objLiteral
- 由于与内存相同,因此对值位置的跟踪与相同,它返回
this
objLiteral
objLiteral.name
'Arvind'
何时为变量赋值,即给定对对象的引用?在创建阶段还是执行阶段?objLiteral
答:
这是我到目前为止的看法。创建阶段:对象被放置在内存中的某个位置,并且是“实时且可访问的”,并且在程序结束之前不会进行垃圾回收。
objLiteral
{}
不,绝对不是。执行上下文以及创建阶段和执行阶段之间的分离与对象(文本)创建无关。它完全与代码执行有关,无论是在全局脚本范围内还是在函数调用中。执行上下文基本上是一个堆栈帧。
对象文本中的对象在执行阶段进行分配、创建和更改,而不是在创建阶段1 期间分配、创建和更改。
因此,在您的示例中发生的情况是:
- 全球语境的创建阶段:
- 变量的分配和初始化
objLiteral
undefined
- 变量的分配和初始化
- 全局脚本的执行阶段:
创建一个对象,创建一个字符串并将其放置在其属性中,创建一个函数(在当前作用域上具有闭包)并将其放置在其属性中,将对象分配给变量
Kumar
.name
.myNameIs
objLiteral
查找变量中的对象,创建一个分配给对象属性的字符串
objLiteral
Arvind
.name
查找变量中的对象,查找其属性,并作为方法调用。这将创建一个新的执行上下文:
objLiteral
.myNameIs
- 函数调用的创建阶段:
- 将创建一个新范围
- 该值设置为方法调用接收方,即对象
this
- 无需在示例中设置变量或参数声明
- 函数调用的执行阶段:
- 查找 中的对象并访问其属性
this
.name
- 该值为 ed,结束函数执行
return
- 查找 中的对象并访问其属性
函数的执行上下文结束,其本地作用域不再被引用,可以进行垃圾回收,全局脚本的执行使用返回的字符串值恢复。
- 函数调用的创建阶段:
垃圾回收也与此无关。一旦对象不再从任何内容(变量或属性)中引用,就会对其进行垃圾回收,一旦变量(和范围)不再从任何内容(实时堆栈帧或闭包)中引用,就会对其进行垃圾回收。
1:我专门写了“from object literals”,因为有些函数对象是在创建阶段从函数
声明创建的
评论