简体   繁体   English

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

[英]What is the correct way to create a Javascript class?

I'm trying to figure out how to construct my Javascript classes (or singleton objects) correctly. 我正在试图弄清楚如何正确构建我的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() { ... }
}

I want to be able to set a couple of properties and assign the methods available. 我希望能够设置几个属性并分配可用的方法。 I would also like to be able to use things like mixins on the objects so I can extend these objects with things like events . 我也想能够使用的东西像混入上的对象,所以我可以用的东西像延长这些对象的事件

I'm trying to figure out how to construct my Javascript classes (or singleton objects) correctly. 我正在试图弄清楚如何正确构建我的Javascript类(或单例对象)。

There's a big difference between those ("classes" and singleton objects). 这些(“类”和单例对象)之间存在很大差异。 Your first couple of examples are one-off objects (singletons). 你的前几个例子是一次性对象(单身人士)。 Your third (last) example creates a constructor function that will allow you to create multiple objects sharing the same prototype. 您的第三个(最后一个)示例创建了一个构造函数 ,该函数允许您创建共享相同原型的多个对象。 I would recommend augmenting the prototype property on the constructor function rather than replacing it as you're doing, eg: 我建议在构造函数上增加 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
};

(Constructor functions, by convention, start with an upper case letter.) (按照惯例,构造函数以大写字母开头。)

Which you use (singleton or constructor function) depends on what you need. 你使用的(单例或构造函数)取决于你需要什么。

As of ES2015 (aka "ES6"), it's simpler, although there's no new syntax for defining a non-method prototype property (your foo ); 从ES2015(又名“ES6”)开始,它更简单,虽然没有新的语法来定义非方法原型属性(你的foo ); there probably will be in ES2017 or ES2018, once this proposal moves forward, but until then: 一旦这个提案向前推进,可能会出现在ES2017或ES2018中,但直到那时:

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

If you need to get into inheritance hierarchies, in the old ES5 syntax there's a fair bit of plumbing involved: 如果你需要进入继承层次结构,在旧的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);
};

...which is why you used to see libraries stepping in, like Prototype's Class stuff, or my own Lineage ; ...这就是为什么你曾经看过踩过的图书馆,比如Prototype的Class东西,或者我自己的Lineage ; those are outdated by ES2015 syntax, though, whcih makes it downright easy: 那些已经过时的ES2015语法已经过时了,这简直太容易了:

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

Re the title of your question: 重新提出问题的标题

What is the correct way to create a Javascript class? 创建Javascript类的正确方法是什么?

There are several equally-correct ways to create "classes" of objects in JavaScript, because JavaScript is a very flexible language. 有几种同样正确的方法可以在JavaScript中创建对象的“类”,因为JavaScript是一种非常灵活的语言。 There are standard constructor functions, "builder" functions, Object.create (on ES5-enabled environments) which lets you do more direct prototypical inheritance, and several others. 有标准的构造函数,“构建器”函数, Object.create (在启用ES5的环境中),它允许您进行更直接的原型继承,以及其他几个。 One of the great things about JavaScript is that you get to choose your style of "class". JavaScript的一大优点是你可以选择你的“课堂”风格。

you can also use something like: 你也可以使用类似的东西:

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

var o=new O(0,0);

If you're looking for a practical solution rather than a theoretical one, you better use a framework. 如果您正在寻找实用的解决方案而不是理论解决方案,那么最好使用框架。

  • Backbone.js has all you need, including mixins and an event system. Backbone.js拥有您所需要的一切,包括mixins和事件系统。

If you need some widgets too, consider 如果你也需要一些小部件,请考虑

Both of them provide a clean architecture and may be used without widgets, but they require a bit more learning than Backbone. 它们都提供了一个干净的架构,可以在没有小部件的情况下使用,但它们需要比Backbone更多的学习。

The inheritance structure that these frameworks provide feels very much like the common class-based one (think Java). 这些框架提供的继承结构非常像基于类的通用结构(想想Java)。 That's because they create special objects internally that merely serve as prototype s for others, and thus take the role of classes. 那是因为他们在内部创建了特殊对象,仅仅作为其他人的prototype ,从而扮演了类的角色。

For example, when you call Ext.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }) , then Ext creates a function " MyClass ", and an anonymous object ( MyClass.prototype ) which holds the methods you provided. 例如,当你调用Ext.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }) ,Ext会创建一个functionMyClass ”和一个匿名对象( MyClass.prototype )。拥有您提供的方法。

If you're targeting a browser or environment that supports ES5, then you can do this: 如果您的目标是支持ES5的浏览器或环境,那么您可以这样做:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM