我是那种需要深入了解一切的人.所以,我已经经历了很多学科的教学,我深入到了原型继承的深度。
我清楚地了解了它在ES5中的工作方式(每个函数都有这个特殊的prototype属性,它指向它所基于的对象。该对象具有.constructor属性,该属性指向函数等)。
现在,让我们看看ES5示例:
function Bunny(name) {
this.name = name
}
Bunny.prototype.sayName = function() {
console.log('Im',this.name)
}这个非常清楚: function获得参数name,它将被分配给一个新对象。
下一行将函数添加到函数的原型中,它将返回当前名称。
现在让我们看看ES6类:
class Fox{
constructor(name){
this.name = name;
}
sayName() {
console.log('Im', this.name)
}
}同样的东西:这里的Constructor就像我们的兔子函数。但是狐狸中的sayName和兔子中的sayName不一样。
让我们创建实例:
let bunny = new Bunny('Henry');
let fox = new Fox('Jerry');现在,检查他们的原型:
console.log(Object.getPrototypeOf(bunny))
console.log(Object.getPrototypeOf(fox))我们能得到什么?
//using repl.it - ES6
{ sayName: [Function] }
{}为什么会这样呢?
我想这可能是因为我们直接在兔子的原型上设置了函数sayName。所以我把它改成了这个
function Bunny(name) {
this.name = name
//Warning - Bad practice ahead!
this.sayName = function() {
console.log('Im',this.name)
}
}结果:
//using repl.it - ES6
{}
{}这是有道理的,如果不是这样的话:
console.log(bunny.hasOwnProperty('sayName'))
console.log(fox.hasOwnProperty('sayName'))这意味着,fox并没有在他身上拥有sayName,无论是原型还是原型都表明它拥有它。我是不是漏掉了什么?为什么他们是不同的?
发布于 2016-11-11 14:47:50
在ES6类中,所有方法都是不可枚举的,因此,当您记录ES6类实例的原型时,会得到一些类似于空对象的内容。
参见此示例:
const obj = new (class {method() {}});
console.log(Object.getPrototypeOf(obj)); // {}
console.log(typeof Object.getPrototypeOf(obj).method); // function
在ES5中,通过将方法分配给类prototype的一个属性来定义方法,这使得它可以枚举。如果您希望实现与ES6类相同的效果,则可以使用Object.defineProperty():
const TestClass = function TestClass() {};
Object.defineProperty(TestClass.prototype, 'method', {
value: function() {},
writable: true,
enumerable: false,
configurable: true,
});
const obj = new TestClass();
console.log(Object.getPrototypeOf(obj)); // {}
console.log(typeof Object.getPrototypeOf(obj).method); // function
fox.hasOwnProperty('sayName')返回false,因为hasOwnProperty()只检查自己的属性,而sayName在原型链中。如果您也想检查prototype链中的属性,可以使用in操作符:'sayName' in fox返回true。
还请参阅MDN上的财产的可数性和所有权。
https://stackoverflow.com/questions/40550246
复制相似问题