jba*_*ndi 5 javascript ecmascript-6 es6-class
我发现ES2015类阻止了他们原型的设置(重新定义).
人们常说,ES2015类只是ES5构造函数和基于原型的继承之上的"语法糖".
但这是行为上的差异......
这种行为是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'));Run Code Online (Sandbox Code Playgroud)
=>重新定义宠物作品的原型
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'));Run Code Online (Sandbox Code Playgroud)
=>重新定义Pet的原型不起作用
任何指向此行为的文档的指针将不胜感激...
这里的区别在于,在创建时class,prototype对象设置为writable: false不能Pet.prototype用赋值替换.Object.getOwnPropertyDescriptor()删除严格模式时,您可以看到通话中的差异.
OP的第一个代码示例显示了这一点:
{
...
"writable": true,
"enumerable": false,
"configurable": false
}
Run Code Online (Sandbox Code Playgroud)
OP的第二个代码示例显示了这一点:
{
...
"writable": false,
"enumerable": false,
"configurable": false
}
Run Code Online (Sandbox Code Playgroud)
该writable属性确定是否Pet.prototype可以为属性分配新值(例如,用新对象替换).一个false值,意味着你不能代替Pet.prototype使用分配.因此,当您的代码尝试执行此操作时,它会失败.
您仍然可以自由地从原型对象添加或删除单个属性,而不是替换整个对象.这对我来说是有意义的,因为替换整个原型对象会撤消整个class定义.Pet.prototype如果您有一个真实的理由来替换它,您可能可以将对象更改为可写.
这在ES 2015规范中有所描述.在14.5.14运行时语义:ClassDefinitionEvaluation中,在步骤16,它执行以下操作:
- 执行MakeConstructor(F,false,proto).
该false论点使得创建的原型不可写(因此无法替换).
而且,如果你再看一下9.2.8 MakeConstructor(),你会在第6步看到这个:
设状态为DefinePropertyOrThrow(F,"prototype",PropertyDescriptor {[[Value]]:prototype,[[Writable]]:writablePrototype,[[Enumerable]]:false,[[Configurable]]:false}).
当writable属性获取false先前传递到它的价值.
人们常说,ES2015类只是ES5构造函数和基于原型的继承之上的"语法糖".但这是行为上的差异......
虽然在定义的方法一般操作class是几乎一样的,这其他答案描述了使用之间有几个其他方面的差异class与手动分配的原型:在JavaScript中,什么是一类和构造函数之间的区别是什么?