鉴于MDN JS Inheritance article,我们有以下几行
我的问题是,为什么要使用Object.create而不是Person.prototype? 我了解链接原型的必要性。 但是这是一个控制台示例,它呈现了对Object.create的调用,实际上并未连接继承的方法:
那是为什么?文章有误吗?
答案 0 :(得分:4)
Teacher.prototype = Person.prototype
这将教师的原型设置为与人的原型相同的对象。因此,如果您进行以下更改:
Teacher.prototype.hi = () => alert("hi");
然后在教师和个人上都存在:
new Person().hi();
那不是创建子类时想要的。如果你这样做
Teacher.prototype = Object.create( Person.prototype );
您创建一个继承人原型的新对象。现在,属性本身不存在于对象本身,而是被继承了。 getOwnPropertyNames
不返回任何值并不意味着这些属性没有被继承,而是相反:它们只是不存在于对象本身,而是存在于其父对象上。
new Teacher().greeting(); // works :)
答案 1 :(得分:3)
Teacher.prototype = Person.prototype
的问题在于,那时没有实际的继承在进行-两个原型都将引用同一对象。如果您继续向Teacher的原型添加函数,例如getClassTaught()
,它将使Person.prototype
变异,而该函数不应该使用该方法。
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() { return this.name; };
function Teacher(name, className) {
this.name = name;
this.className = className;
}
Teacher.prototype = Person.prototype;
Teacher.prototype.getClassTaught = function() { return this.className; };
const person = new Person();
console.log('getClassTaught' in person);
如果不完全替换Person
个函数,您将也无法将它们隐藏起来。例如,如果greeting()
上有一个Person.prototype
函数,并且您为greeting()
分配了另一个Teacher.prototype
函数,那么您将覆盖Person.prototype
上的函数-其他person
调用greeting()
可能不再起作用,因为该函数现在是特定于教师的,而不是Person-generic的。
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() { return this.name; };
Person.prototype.greeting = function() { return 'Hi, I am ' + this.name; };
function Teacher(name, className) {
this.name = name;
this.className = className;
}
Teacher.prototype = Person.prototype;
Person.prototype.greeting = function() { return 'Hi, I am Teacher ' + this.name; };
const person = new Person('Bob');
console.log(person.greeting());
getOwnPropertyNames
仅在对象本身上直接显示属性名称 -不显示继承的属性名称。当您使用Object.create(Person.prototype)
时,greeting
是从Person
原型继承而来的。它不是直接位于Teacher.prototype
上,因此不会显示在getOwnPropertyNames
中。