-3

给定MDN JS Inheritance 文章,我们有这些行

在此处输入图像描述

我的问题是,为什么要使用 Object.create 而不仅仅是 Person.prototype?我了解链接原型的必要性。但这里是控制台示例,呈现对 Object.create 的调用实际上没有连接继承的方法: 在此处输入图像描述

这是为什么?是文章中的错误吗?

4

2 回答 2

4
 Teacher.prototype = Person.prototype

这将教师的原型设置为与人员原型相同的对象。所以如果你改变它:

Teacher.prototype.hi = () => alert("hi");

那么这对教师和个人都存在:

new Person().hi();

这不是您在创建子类时想要的。如果你这样做

Teacher.prototype = Object.create( Person.prototype );

您创建了一个新对象,该对象继承了个人原型。现在属性不存在于对象本身,但它们是继承的。什么getOwnPropertyNames都不返回并不意味着属性不是继承的,而是相反:它们只是不存在于对象本身,而是存在于其父对象上。

 new Teacher().greeting();  // works :)
于 2018-07-10T07:08:58.317 回答
3

问题Teacher.prototype = Person.prototype在于,没有实际的继承发生——两个原型都将引用同一个对象。如果您继续向 Teacher 的原型添加一个函数,例如getClassTaught(),那将 mutate 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()函数 on Person.prototype,而您将另一个greeting()函数分配给Teacher.prototype,您将覆盖该函数 on Person.prototype- other persons 调用greeting()可能不再起作用,因为该函数现在是 Teacher-specific,而不是 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)继承原型;它不是直接打开的,所以它不会出现在.greetingPersonTeacher.prototypegetOwnPropertyNames

于 2018-07-10T07:07:41.593 回答