我发现 ES2015 类阻止设置(重新定义)它们的原型(prototype)。
人们经常声称 ES2015 类只是 ES5 构造函数和基于原型(prototype)的继承之上的“语法糖”。
但这是行为上的差异......
这种行为是 ES2015 规范的一部分吗?我没有找到关于此的任何文档......
以下示例说明了差异:
function Pet() {}
Pet.prototype.eat = () => {
console.log('Pet is eating ...');
}
Pet.prototype = {eat: function(){console.log('Pet is REALLY eating ...')}};
const pet = new Pet();
pet.eat(); // -> Pet is REALLY eating ...
console.log(Object.getOwnPropertyDescriptor(Pet, 'prototype'));
=> 重新定义宠物作品原型(prototype)
class Pet {
eat() {
console.log('Pet is eating ...');
}
}
Pet.prototype = {eat: function(){console.log('Pet is REALLY eating ...')}};
const pet = new Pet();
pet.eat(); // -> Pet is eating ...
console.log(Object.getOwnPropertyDescriptor(Pet, 'prototype'));
=> 重新定义 Pet 的原型(prototype)不起作用
任何指向此行为文档的指针都将不胜感激......
最佳答案
这里的区别在于,当使用class
创建时,prototype
对象被设置为writable: false
,这样你就无法替换Pet.prototype
赋值。当您移除严格模式时,您可以在 Object.getOwnPropertyDescriptor()
调用中看到这种差异。
OP 的第一个代码示例显示了这一点:
{
...
"writable": true,
"enumerable": false,
"configurable": false
}
OP 的第二个代码示例显示了这一点:
{
...
"writable": false,
"enumerable": false,
"configurable": false
}
writable
属性决定了属性 Pet.prototype
是否可以被赋予一个新值(例如替换为一个新对象)。 false
值意味着您不能使用赋值替换 Pet.prototype
。因此,当您的代码尝试这样做时,它会失败。
您仍然可以自由地在原型(prototype)对象中添加或删除单个属性,只是不能替换整个对象。这对我来说有些意义,因为替换整个原型(prototype)对象会撤消整个 class
定义。如果您有现实世界的理由替换它,您可能会将 Pet.prototype
对象更改为可写。
这在 ES 2015 规范中有描述。在 14.5.14 Runtime Semantics: ClassDefinitionEvaluation ,在第 16 步,它这样做:
- Perform MakeConstructor(F, false, proto).
false
参数使创建的原型(prototype)不可写(因此无法替换)。
然后,如果你再看看 9.2.8 MakeConstructor() ,您会在第 6 步中看到:
Let status be DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false}).
writable
属性获取先前传递给它的 false
值。
It is often claimed that ES2015 classes are just "syntactic sugar" on top of ES5 constructor functions and prototype based inheritance. But this is a difference in behavior...
虽然 class
中定义的方法的一般操作几乎相同,但另一个答案描述了使用 class
与手动分配给原型(prototype)之间的其他几个区别: In javascript, what are the differences between a class and a constructor?
关于javascript - ES2015 类阻止设置原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50543757/