【问题标题】:Why set a property both on the function and its prototype?为什么要在函数及其原型上都设置一个属性?
【发布时间】:2026-02-18 07:00:01
【问题描述】:

我试图了解 JavaScript 的 OOP 模型,所以我正在阅读这篇文章: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

下面的代码很有趣:

function Person(gender) {
    this.gender = gender;
    alert('Person instantiated');
}

Person.prototype.gender = '';
var person1 = new Person('Male');
var person2 = new Person('Female');
//display the person1 gender
alert('person1 is a ' + person1.gender); // person1 is a Male

对我来说有趣但不清楚的是这一行:

Person.prototype.gender = '';

我不明白,所以我用那行和没有它的代码测试了代码。

代码在这两种情况下都可以正常工作。

所以我的问题是:

作者为什么要加那行?

【问题讨论】:

  • 在这种情况下是不必要的。但是想象一下,如果 this.gender = gender; 被省略(或者可能包含在条件中)会发生什么,你知道吗?
  • @Bergi 你的意思是避免调用 null 或 undefined?
  • @stackunderflow Bergi 指的是它充当默认参数值的情况。但是,我认为最好避免它,因为它缓慢、不清楚,并且如果发生突变会产生意想不到的结果。

标签: javascript oop prototype


【解决方案1】:

您不应在原型上设置数据。很多时候,从经典语言接触 JavaScript 的人试图模仿经典继承,但原型链的不对称性(设置总是本地但getting链)意味着它是不切实际的。有关原型继承的更多信息,click here

原型用于跨实例共享功能。把函数放在那里。共享数据,see this answer

那篇将性别放在原型上的文章是错误的。这就是为什么在 ES6 中,最大限度地最小化的类在原型上设置函数,而不是数据成员。请参阅this article,了解为什么要避免原型上的数据。

我已经修复了 MDN 文章,不错。

【讨论】:

  • 不是我,但“你不应该在原型上设置数据。”缺乏解释。我可以想象很多有用的用例。
  • 如果您需要一些“默认数据”来处理未分配属性的情况,那么到处都是。在其他基于原型的 OOP 语言中并不少见。
  • @Bergi 即使我们忽略了缓慢的事实,因为它会强制隐藏类去优化。您意识到这意味着错误地更改原型上的默认值(例如,您获得了对它的直接引用)会更改 每个实例 上的值,您认为有多少人会受到影响?更不用说,我不确定所有开发人员都会意识到不对称(这就是为什么我们有臭名昭著的 for..in 错误)
  • 我给了你 1+ 的答案,并将其标记为已接受的答案,但是你的答案非常紧凑且非常技术性,新手(我)不会轻易消化它,比如“但是原型链的不对称性(设置总是本地的,但会爬上链)“..thanx
  • @stackunderflow 啊,我不想再次重写已经写在 Stack Overflow 中的答案,我会添加参考。对不起。