9

我试图弄清楚如何正确构建我的 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之类的东西来扩展这些对象。

4

4 回答 4

8

我试图弄清楚如何正确构建我的 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 中出现,但在那之前:

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 的一大优点是您可以选择自己的“类”风格。

于 2012-05-26T21:10:59.053 回答
1

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

function O(x,y) {
   this.x=x;
   this.y=y;
   this.method=function() {...}
   return this;
}

var o=new O(0,0);
于 2012-05-26T21:11:20.500 回答
1

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

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

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

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

这些框架提供的继承结构感觉很像常见的基于类的结构(想想 Java)。那是因为它们在内部创建了特殊的对象,这些对象仅作为prototype其他对象的 s,因此起到了类的作用。

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

于 2012-05-27T07:36:17.667 回答
0

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

var Person = {
  foo: ...,
  bar: ...
};

var Mike = Object.create(Person, { baz: ... });
于 2012-05-26T21:14:42.653 回答