我是否应该使用prototype?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我正在创建一个向量类,它可以包含三个数值。然而,可以对这样的向量进行许多操作--例如获取大小、加或减去另一个向量等。

我想知道这些函数是应该编码为Vectorclass的原型函数,还是应该在构造函数中定义它们?

那么,这两种方法中哪一种更可取?

function Vector3D(x, y, z) {
    this.x = x;
    this.y = y
    this.z = z;
}

Vector3D.prototype.magnitude = function() {
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
};

function Vector3D(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;

    this.magnitude = function() {
        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
    };
}
提问于
用户回答回答于

这样做的两个主要好处:

  1. 函数不会多次创建。如果在造函数中定义函数,则每次调用构造函数时都会给定义的每个函数创建一个新的匿名函数。原型是静态对象,Vector3D的每个实例都将简单引用原型函数。
  2. prototype是一个可以轻松操作的单个对象。这提供了很大的灵活性; 我只能提供一些可以提供的例子:
    1. 如果你想创建一个子类,例如Vector3DSpecial,你可以简单地克隆Vector3D.prototype并分配它Vector3DSpecial.prototype。虽然你也可以通过构造函数来做到这一点Vector3DSpecial.prototype = new Vector3D();,但构造函数可能包含将在该简单原型分配中执行的副作用,因此应该避免。通过原型,甚至可以只选择原型中的特定功能以复制到新类中。
    2. 添加方法Vector3D仅仅是为原型添加属性,并允许将代码更容易地拆分/组织成多个文件,或者允许动态地在代码的其他部分添加方法。当然,可以在构造函数和原型中添加方法的组合,但这种方法不一致,并可能导致更复杂的进度。

什么时候不使用prototype?对于singleton对象,例如与页面交互的控制器,可以将工作委托给其他对象。全球“通知”对象就是这样一个例子。在这里,扩展是不太可能的,并且该对象只创建一次,使原型成为额外的(概念上的)复杂性。

用户回答回答于

prototype方法只适用于公共属性,如果将x,y,z作为“私有”变量进行跟踪,则原型将无法工作。

我会使用后者,因为可能需要只使用私有/内部变量的方法,但这一切都取决于上下文。

function Vector3D(x, y, z) {
   // x, y, z is automatically in this scope now, but as private members.
   this.magnitude = function() {
        return Math.sqrt(x * x + y * y + z *z);
   }
}

扫码关注云+社区