【问题标题】:What is the correct way to create a Javascript class?创建 Javascript 类的正确方法是什么?
【发布时间】:2012-06-01 22:37:25
【问题描述】:

我正在尝试弄清楚如何正确构建我的 Javascript 类(或单例对象)。

var obj = new Object();
obj.foo = 'bar';
obj.method = function() { ...}

var obj = {
    foo : 'bar',
    method : function() { ...}
}

var obj = function(){}
obj.prototype = {
    foo : 'bar',
    method: function() { ... }
}

我希望能够设置几个属性并分配可用的方法。我还希望能够在对象上使用mixins 之类的东西,这样我就可以使用events 之类的东西来扩展这些对象。

【问题讨论】:

  • 规则#1:永远不要使用new Object()
  • @minitech,你确定吗?他们一定是出于某种原因做到了。
  • @Xeoncross 他们也制作了new Window,但你不能使用它;)
  • and new Array, and new Number, and new... 最好使用文字
  • 将字符串文字传递给new String 构造函数是不是很讽刺?

标签: javascript oop object


【解决方案1】:

我正在尝试弄清楚如何正确构建我的 Javascript 类(或单例对象)。

这些(“类”和单例对象)之间存在很大差异。您的前几个示例是一次性对象(单例)。您的第三个(最后一个)示例创建了一个 构造函数,它允许您创建共享同一原型的多个对象。我建议扩充构造函数上的prototype 属性,而不是像你正在做的那样替换它,例如:

var Thingy = function() {   // Or use a function declaration rather than expression
    // Optional initialization code here
};
Thingy.prototype.foo = 'bar';
Thingy.prototype.method = function() {
    // Method code here
};

(按照惯例,构造函数以大写字母开头。)

您使用哪个(单例或构造函数)取决于您的需要。

从 ES2015(又名“ES6”)开始,它更简单,尽管没有用于定义非方法原型属性的新语法(您的 foo);可能会在 ES2017 或 ES2018 中,一旦this proposal 向前移动,但在那之前:

class Thingy {
    constructor() {
        // Optional initialization code here
    }
    method() {
    // Method code here
    }
}
Thingy.prototype.foo = 'bar';

如果您需要进入继承层次结构,在旧的 ES5 语法中会涉及到相当多的管道:

var Base = function() {
};
Base.prototype.method = function(arg1) {
    // ...
};

var Derived = function() {
    Base.call(this);
};
Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;
Derived.prototype.method = function(arg1) {
    // Using Base's `method`, if desired, is a bit ugly:
    Base.prototype.method.call(this, arg1);
};

...这就是为什么您过去经常看到库介入的原因,例如 Prototype 的 Class 的东西,或者我自己的 Lineage;这些在 ES2015 语法中已经过时了,不过,这让它变得非常容易:

class Base {
    method(arg1) {
        // ...
    }
}
class Derived extends Base {
    method(arg1) {
        // Use's the superclass's `method`, if desired, is easy:
        super.method(arg1);
    }
}

关于您问题的标题

创建 Javascript 类的正确方法是什么?

有几种同样正确的方法可以在 JavaScript 中创建对象的“类”,因为 JavaScript 是一种非常灵活的语言。有标准的构造函数、“builder”函数、Object.create(在支持 ES5 的环境中)可以让您进行更直接的原型继承,以及其他几个。 JavaScript 的一大优点是您可以选择自己的“类”风格。

【讨论】:

    【解决方案2】:

    你也可以使用类似的东西:

    function O(x,y) {
       this.x=x;
       this.y=y;
       this.method=function() {...}
       return this;
    }
    
    var o=new O(0,0);
    

    【讨论】:

      【解决方案3】:

      如果您的目标是支持 ES5 的浏览器或环境,那么您可以这样做:

      var Person = {
        foo: ...,
        bar: ...
      };
      
      var Mike = Object.create(Person, { baz: ... });
      

      【讨论】:

        【解决方案4】:

        如果您正在寻找实际解决方案而不是理论解决方案,您最好使用框架。

        • Backbone.js 拥有您所需要的一切,包括 mixins 和事件系统。

        如果您也需要一些小部件,请考虑

        它们都提供了一个干净的架构,并且可以在没有小部件的情况下使用,但它们需要比 Backbone 更多的学习。

        这些框架提供的继承结构感觉很像常见的基于类的结构(想想 Java)。那是因为他们在内部创建了特殊的对象,这些对象只是为其他人充当prototypes,因此承担了类的角色。

        例如,当您调用 Ext.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }) 时,Ext 会创建一个 function "MyClass",以及一个保存您提供的方法的匿名对象 (MyClass.prototype)。

        【讨论】:

          猜你喜欢
          • 2016-02-07
          • 1970-01-01
          • 2021-06-27
          • 1970-01-01
          • 2021-08-24
          • 1970-01-01
          • 1970-01-01
          • 2012-12-28
          • 1970-01-01
          相关资源
          最近更新 更多