【问题标题】:JS inheritance - MDN articleJS 继承 - MDN 文章
【发布时间】:2018-12-17 22:23:04
【问题描述】:

鉴于MDN JS Inheritance article,我们有这些行

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

这是为什么呢?是不是文章写错了?

【问题讨论】:

  • 能否请您用实际代码替换代码图像
  • 我同意这篇文章有点混乱。它无法解释有两种东西通常被称为某物的“原型”。一个是函数的.prototype属性,另一个是对象的原型(你可以用Object.getPrototypeOf得到这个。文章的想法是Object.getPrototypeOf(Teacher.prototype) === Person.prototype,而不是Teacher.prototype === Person.prototype。这是什么Object.create 确实如此。
  • @vnt 对不起,不。我希望即使不运行代码也知道它的人的答案(没有冒犯,但我可以自己运行代码:),如果你在没有控制台的情况下知道它 - 你真的知道它)

标签: javascript inheritance prototypal-inheritance javascript-inheritance


【解决方案1】:
 Teacher.prototype = Person.prototype

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

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

那么这既存在于老师身上,也存在于人身上:

new Person().hi();

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

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

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

 new Teacher().greeting();  // works :)

【讨论】:

    【解决方案2】:

    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 函数。例如,如果Person.prototype 上有一个greeting() 函数,并且您将另一个greeting() 函数分配给Teacher.prototype,您将覆盖Person.prototype 上的函数 - 其他persons 调用greeting() 可能不再起作用,因为该函数现在是特定于教师的,而不是通用的。

    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 上。

    【讨论】:

    • 谢谢!!!我现在明白了。但是,没有在自己的方法上为教师显示的“问候”(并为个人显示)呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多