javascript - 为什么在原型(prototype)中定义属性被认为是一种反模式

标签 javascript prototype anti-patterns prototype-programming prototypal-inheritance

我经常看到这种模式来定义javascript对象

function Person(name) {
    this.name = name;
}
Person.prototype.describe = function () {
    return "Person called "+this.name;
};

并且在 this article它说直接向原型(prototype)对象添加属性被认为是一种反模式。

来自“基于经典类”的语言,必须定义方法之外的属性听起来不太正确,而且在 javascript 中,方法应该只是一个具有函数值的属性(我在这里吗?)

我想知道是否有人可以解释这一点,或者甚至建议一种更好的方法来处理这些情况

最佳答案

在通常的面向对象语言中,您有一个描述成员、方法和构造函数的类的定义。

在 JS 中,“类”的定义(它不像其他语言那样真正是类......有时使用术语伪类)是构造函数本身。如果您的对象由 name 参数化,那么编写

是有意义的
function Person(name) {
    this.name = name;
}

即必须在构造函数中设置属性 name

当然可以这样写

function Person(name) {
    this.name = name;
    this.describe = function() { ... };
}

它会如您所愿地工作。

但是,在这种情况下,您将在每次调用构造函数时创建一个单独的方法实例。

另一方面,这里:

Person.prototype.describe = function () {
    return "Person called "+this.name;
};

您只需定义一次方法。 Person 的所有实例都将收到指向 Person.prototype 的指针(称为 __proto__ 并且在大多数浏览器中程序员无法访问)。所以如果你打电话

var myPerson = new Person();
myPerson.describe();

它会起作用,因为 JS 直接在对象中查找对象成员,然后在其原型(prototype)中,一直到 Object.prototype

要点是,在第二种情况下,只会存在该函数的一个实例。您可能会同意这是一个更好的设计。即使您不这样做,也只会占用更少的内存。

关于javascript - 为什么在原型(prototype)中定义属性被认为是一种反模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11904203/

相关文章:

design-patterns - 为什么 'smoke and mirrors' 是一种反模式?

JavaScript 锐化图像和边缘检测不起作用

javascript - 在外部 .js 文件中使用 .vue 组件时如何使用相同的变量?

javascript - 当我尝试使用 Google Assistant 时,将上下文从一个意图传递到另一个意图时获取 "null"上下文

javascript - JavaScript 中的类属性

Javascript对象原型(prototype)错误

javascript - 对象结构的 Eval 字符串

javascript - 使用原型(prototype)访问对象属性

java - 双重检查锁定 (DCL) 及其修复方法

java - 我如何重写此代码片段,以便我不手动/显式调用注入(inject)器?