使用原型JavaScript - 最佳实践

9

目前我正在参与一个编写面向对象JavaScript的项目。在这个项目中,我看到了两种不同的定义类的方法:

1:一次性在原型上声明函数

My.Namespace.ClassName = function(param1, param2) {
   this.member1 = param1;
   this.member2 = param2;
};

My.Namespace.ClassName.prototype = {
   myFunction1: function() {
      return this.member1 + " " + this.member2;
   },

   myFunction2: function(param1) {
      this.member3 = paraml;
   }
};

2:在原型上单独准备每个函数

My.Namespace.ClassName = function(param1, param2) {
   this.member1 = param1;
   this.member2 = param2;
};

My.Namespace.ClassName.prototype.myFunction1 = function() {
   return this.member1 + " " + this.member2;
};

My.Namespace.ClassName.prototype.myFunction2 = function(param1) {
   this.member3 = paraml;
};

这两个示例中的JavaScript行为是否有差异,还是只是样式上的不同?

个人认为没有行为差异,但我感觉可能有微妙的差别,目前还未发现。

此外,我想知道这是否是常见做法,或者是否有更好的定义类的方式。

1个回答

8

有一个微妙的差别。在第一种方法中,当你覆盖原型时,会丢失一个属性。那就是constructor,它指向你的函数。构造函数允许你重新创建它所代表的对象类型。

你可以通过手动设置来轻松地获得它,因此可以使用第一种方法:

My.Namespace.ClassName.prototype = {
   myFunction1: function() {
      return this.member1 + " " + this.member2;
   },

   myFunction2: function(param1) {
      this.member3 = paraml;
   },
   constructor: My.Namespace.ClassName
};

另请参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor


你能否详细解释一下你所说的“在第一种方法中,当你覆盖原型时,有一个属性现在已经丢失”的意思?你是指在调用“var obj = new My.Namespace.ClassName(“value1”,“value2”)”之前和之后,My.Namespace.ClassName.constructor存在差异吗? - hwcverwe
不 - My.Namespace.ClassName.prototype 带有一个 constructor 属性。当你覆盖原型时,构造函数会丢失。 - Scimonster
已经接受,不过有一个问题:我可以将两种风格结合起来吗?或者这会在某些地方引起问题吗? - hwcverwe
如果您使用此处的代码来添加构造函数属性,则没有理由不能像其他对象一样向原型添加更多属性。 - Scimonster
有没有一种方法被认为比另一种更好的实践? - tforgione

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接