【问题标题】:JavaScript Prototype property not added to its inherited objectsJavaScript Prototype 属性未添加到其继承的对象
【发布时间】:2019-09-06 15:10:14
【问题描述】:

我正在关注MDN 关于添加属性的指南,这就是我的代码的样子

'use strict';

function Employee() {
    this.name = '';
    this.dept = 'general';
}
Employee.prototype.specialty = 'none';

function Manager() {
    Employee.call(this);
    this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;

function WorkerBee() {
    Employee.call(this);
    this.projects = [];
}
WorkerBee.prototype = Object.create(Employee.prototype);
WorkerBee.prototype.constructor = WorkerBee;

function SalesPerson() {
    WorkerBee.call(this);
    this.dept = 'sales';
    this.quota = 10;
}
SalesPerson.prototype = Object.create(WorkerBee.prototype);
SalesPerson.prototype.constructor = SalesPerson;

function Engineer() {
    WorkerBee.call(this);
    this.dept = 'engineering';
    this.machine = '';
}
Engineer.prototype = Object.create(WorkerBee.prototype);
Engineer.prototype.constructor = Engineer;

let mark = new WorkerBee;
console.log(mark);

mark.name = 'Doe, Mark';
mark.dept = 'admin';
mark.projects = ['navigator'];
console.log(mark);

mark.bonus = 3000;
console.log(mark);

当我运行它时,我没有看到 mark 对象的 specialty 属性。

WorkerBee { name: '', dept: 'general', projects: [] }
WorkerBee { name: 'Doe, Mark', dept: 'admin', projects: [ 'navigator' ] }
WorkerBee {
  name: 'Doe, Mark',
  dept: 'admin',
  projects: [ 'navigator' ],
  bonus: 3000 }

我错过了什么?

谢谢


更新

根据@adiga 的回答,我能够在原型链中找到specialty 属性。

【问题讨论】:

    标签: javascript inheritance prototype


    【解决方案1】:

    这是因为它不是实例属性,而是继承属性。它实际上就在那里,检查它只是 console.log(mark.specialty)。

    编辑以扩展答案

    继承的属性意味着该属性存在于原型链而不是它自身的实例中:当您将某些东西分配给 this 时 this.age = 13; 您正在设置一个实例属性,当您将某些东西分配给用于创建实例的原型时,您正在设置一个继承属性,在其他语言中称为静态属性(在 ES6 中称为静态属性)。

    当你尝试读取像object.someProperty 这样的属性时,JS 引擎首先查看实例属性,如果它存在,它会返回它,否则它会查看原型链(从一个原型到它的父原型)直到它要么找到属性,要么到达最终安装的原型,在这种情况下返回 null 并返回 undefined)

    【讨论】:

    • 谢谢@ehab 的回答。这绝对有帮助。
    【解决方案2】:

    同样的原因,即使您可以从 mark 对象调用它们,您也无法看到 toStringhasOwnProperty 属性。 specialty 不是mark 对象的自己的 属性,但它是继承的。

    浏览器的控制台只显示对象自己的属性。展开mark对象的__proto__,就可以看到继承的属性了。

    【讨论】:

    • 有意思,所以mark中的name属性与Employee.name无关?
    • @daydreamer 抱歉,我删除了那个位。 Employee.call(this) 将直接将属性name 添加到mark 对象。但是如果你设置mark.specialty = "some value",它会直接给mark对象增加一个属性。原型链中的specialty 仍将保留"none"
    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 2014-11-04
    • 2014-05-29
    相关资源
    最近更新 更多