当您使用 'super' 时,'this' 是什么意思?
What does 'this' mean when you use 'super'?
<script>
const base = {
name: "C",
sayHi() {
console.log(this.name); // A how and why 'this' refers to the derived2 object??
},
};
const derived = {
__proto__: base,
name: "B",
sayHi() {
super.sayHi();
},
};
const derived2 = {
__proto__: derived,
name: "A",
sayHi() {
super.sayHi();
},
};
derived2.sayHi();
</script>
我以为基础对象中的this
指的是派生对象
因为derived.sayHi
中的super
表示derived.__proto__
(基础对象)。
我了解到方法中的 this
指的是调用它的对象。
但实际上 this
在基础对象上打印 derived2
而 console.log(this.name)
是 A
.
它是如何工作的?
我知道super = Obejct.getPrototypeOf( [[ Homeobject ]] )
我误会了什么?
使用函数继承时,this
变量不会转换为不同的 类。 this
等于 函数最初在 上调用的对象,按原样。 (箭头函数有一些例外)。
class A {
sayHi() { console.log(this.prototype.name); }
}
class B extends A {
sayHi() { super.sayHi(); }
}
const obj1 = new B();
const obj2 = new A();
obj1.sayHi(); // B.sayHi calls A.sayHi with `this` being simply obj1.
// Logs "B"
obj2.sayHi(); // A.sayHi runs with `this` being obj2.
// Logs "A"
this
指的是“基础 class” 一开始没什么意义。调用(非静态)方法时,所有 this
可以引用的是某个对象的 实例 。
想象一个修改属性的父方法。如果不是调用该方法的实例,它应该修改哪个实例?显然,this
只能引用调用任何方法的实例,super
或不。
据我所知,MDN 是 not explicit about it。也许他们认为这不值得一提?
但是,这种机制确实使 ECMAScript 引擎中 this
的处理比以前更加复杂:)
假设我是对的,这就是 ECMA 标准对此事的说法:
§ 13.3.7:the
super
keyword
,在 SuperProperty : super . IdentifierName
部分(对应于你的 super.A
),告诉我们这个句法元素将被评估为 MakeSuperPropertyReference
,其值 this
在当前“环境记录”中找到(派生的 class你的例子)和指定的 属性 键(即方法的名称,在你的例子中是 A
)。
上面的部分涵盖了将对象视为属性的字符串索引数组的情况(即 super["A"]
表示法等同于 super.A
)
§ 13.3.7.3 MakeSuperPropertyReference
告诉我们这个调用将 return a ReferenceRecord
§ 6.2.4 The Reference Record Specification Type
解释说“在 super
] 的情况下,[[ThisValue]]
字段保存此值 在创建参考记录时"
§ 13.3.6.2 EvaluateCall
应用于父对象方法将命中伪代码的大小写 1.b
并取回原始调用者的 this
值(即您派生的 class 实例)。
因此,显然,虽然 [HomeObject]
用于遍历原型链,但 this
的处理是用另一种逻辑定义的。
不要问我为什么:我没有写规范,我只是在煞费苦心地试图理解它:)
<script>
const base = {
name: "C",
sayHi() {
console.log(this.name); // A how and why 'this' refers to the derived2 object??
},
};
const derived = {
__proto__: base,
name: "B",
sayHi() {
super.sayHi();
},
};
const derived2 = {
__proto__: derived,
name: "A",
sayHi() {
super.sayHi();
},
};
derived2.sayHi();
</script>
我以为基础对象中的this
指的是派生对象
因为derived.sayHi
中的super
表示derived.__proto__
(基础对象)。
我了解到方法中的 this
指的是调用它的对象。
但实际上 this
在基础对象上打印 derived2
而 console.log(this.name)
是 A
.
它是如何工作的?
我知道super = Obejct.getPrototypeOf( [[ Homeobject ]] )
我误会了什么?
使用函数继承时,this
变量不会转换为不同的 类。 this
等于 函数最初在 上调用的对象,按原样。 (箭头函数有一些例外)。
class A {
sayHi() { console.log(this.prototype.name); }
}
class B extends A {
sayHi() { super.sayHi(); }
}
const obj1 = new B();
const obj2 = new A();
obj1.sayHi(); // B.sayHi calls A.sayHi with `this` being simply obj1.
// Logs "B"
obj2.sayHi(); // A.sayHi runs with `this` being obj2.
// Logs "A"
this
指的是“基础 class” 一开始没什么意义。调用(非静态)方法时,所有 this
可以引用的是某个对象的 实例 。
想象一个修改属性的父方法。如果不是调用该方法的实例,它应该修改哪个实例?显然,this
只能引用调用任何方法的实例,super
或不。
据我所知,MDN 是 not explicit about it。也许他们认为这不值得一提?
但是,这种机制确实使 ECMAScript 引擎中 this
的处理比以前更加复杂:)
假设我是对的,这就是 ECMA 标准对此事的说法:
§ 13.3.7:the
super
keyword
,在 SuperProperty : super . IdentifierName
部分(对应于你的 super.A
),告诉我们这个句法元素将被评估为 MakeSuperPropertyReference
,其值 this
在当前“环境记录”中找到(派生的 class你的例子)和指定的 属性 键(即方法的名称,在你的例子中是 A
)。
上面的部分涵盖了将对象视为属性的字符串索引数组的情况(即 super["A"]
表示法等同于 super.A
)
§ 13.3.7.3 MakeSuperPropertyReference
告诉我们这个调用将 return a ReferenceRecord
§ 6.2.4 The Reference Record Specification Type
解释说“在 super
] 的情况下,[[ThisValue]]
字段保存此值 在创建参考记录时"
§ 13.3.6.2 EvaluateCall
应用于父对象方法将命中伪代码的大小写 1.b
并取回原始调用者的 this
值(即您派生的 class 实例)。
因此,显然,虽然 [HomeObject]
用于遍历原型链,但 this
的处理是用另一种逻辑定义的。
不要问我为什么:我没有写规范,我只是在煞费苦心地试图理解它:)