【问题标题】:Prototype concept as given in Mozilla docsMozilla 文档中给出的原型概念
【发布时间】:2014-12-08 13:09:37
【问题描述】:

我正在阅读 Mozilla 文档 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model) 中给出的 JavaScript 对象模型,并且有一个可能非常愚蠢的问题。

如您所见,它描述了一个基于原型的继承层次结构(Manager 继承自 Employee),如下所示:

function Employee() {
  this.name = "";
  this.dept = "general";
}

function Manager() {
  Employee.call(this);
  this.reports = [];
}

Manager.prototype = Object.create(Employee.prototype);

最后一行不应该说Employee而不是Employee.prototype吗?如果我们要构建原型链,我认为应该是前者。请解释一下。

【问题讨论】:

  • 因为Object.create 需要一个原型作为第一个参数。
  • @Passerby 在这种情况下,namedept 会自动添加到 Employee.prototype 吗?如果没有,我想知道Manager 如何访问它们? Object.create() 函数是否神奇地沿着原型链向下移动并找出添加了哪些属性?
  • IMO namedept 在这种情况下不低于 Employee.prototype,它们只是附加到每个 Employee instance 的两个属性。 Manager instances 也可以通过Employee.call(this)“构造”过程获得这两个属性。
  • @Passerby 非常有趣的观察!是的,我完全忘记了call() 方法。
  • 另外,name is a property in Function's prototype,这可以解释为什么@VladZ 中缺少name。的案例 #2。

标签: javascript


【解决方案1】:

这是因为Object.create 需要一个原型作为第一个参数。您可以在以下link 找到所有规格。

我还继续测试了您建议的案例,它显示了一个有趣的行为。

案例#1

function Employee() {
  this.name = "";
  this.dept = "general";
}

function Manager() {
  Employee.call(this);
  this.reports = [];
}

Manager.prototype = Object.create(Employee.prototype);

如果我们创建一个新的 Manager(),我们会得到以下结果:

var x = new Manager();
console.log(x);

控制台输出经理{name:“”,部门:“general”,报告:Array[0]}

如果我们根据您的建议更改代码并将 Employee 作为参数而不是 Employee.prototype 传递:

案例#2

function Employee() {
  this.name = "";
  this.dept = "general";
}

function Manager() {
  Employee.call(this);
  this.reports = [];
}

Manager.prototype = Object.create(Employee);

如果我们现在继续创建一个 Manager,新创建的对象将不会像 案例 #1 中那样包含 name 属性:

var y = new Manager();
console.log(y);

控制台输出经理{部门:“一般”,报告:数组[0]}

编辑#1

我做了更多研究,并在 Stackoverflow (link) 上发现了另一个问题,可以解释这种行为。

它似乎与构造函数的行为方式有关。

正如上述线程中所述,当您使用 new 运算符创建对象时,您基本上创建了一个继承自该对象原型的新对象。

因此,由于 JavaScript 继承是对象到对象的,因此将原型作为您希望新对象继承的蓝图传递是有意义的。

【讨论】:

  • 谢谢。我可以看到行为有何不同,但我仍然认为文档没有使案例足够清楚。以下是您提供的链接对传递给Object.create 的参数的说明:应该是新创建对象的原型的对象。现在,正如我所见,我们希望Employee 成为Manager 的原型。 Employee.prototype,在我看来,甚至没有 name 和 dept 属性。那么,这些是如何被继承的呢?我认为普通对象和原型对象之间没有区别。 . .
  • @dotslash:我做了更多的研究,并在 Stackoverflow 上找到了一些额外的信息。请查看编辑#1。希望对您有所帮助!
  • @dotslash 不同之处之一是,Employee 是一个 Function 对象(原型“函数”的对象)(将其视为“类”/“构造函数”),而 Employee.prototype只是一个普通对象,“描述”Employee 的结构。
猜你喜欢
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 2011-07-03
  • 2012-08-25
  • 2013-03-30
  • 2021-11-28
  • 2018-08-28
  • 1970-01-01
相关资源
最近更新 更多