JS继承-MDN文章

时间:2018-07-10 07:01:46

标签: javascript inheritance prototypal-inheritance javascript-inheritance

鉴于MDN JS Inheritance article,我们有以下几行

enter image description here

我的问题是,为什么要使用Object.create而不是Person.prototype? 我了解链接原型的必要性。 但是这是一个控制台示例,它呈现了对Object.create的调用,实际上并未连接继承的方法: enter image description here

那是为什么?文章有误吗?

2 个答案:

答案 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中。