Вопрос по oop, javascript – Как правильно создать класс Javascript?

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() { ... }
}

Я хочу иметь возможность установить пару свойств и назначить доступные методы. Я также хотел бы иметь возможность использовать такие вещи, какПримеси на объекты, чтобы я мог расширить эти объекты с такими вещами, какСобытия.

Правило № 1: Никогда не используйтеnew Object(). Ry-♦
Разве это не иронично, что вы передаете строковый литерал вnew String конструктор? Niet the Dark Absol
@minitech, ты уверен? Должно быть, они сделали это по какой-то причине. Xeoncross
и новый массив, и новый номер, и новый ... лучше использовать буквальное elclanrs
@Xeoncross Они сделалиnew Window тоже, но вы не можете его использовать;) Niet the Dark Absol

Ваш Ответ

4   ответа
8

m trying to figure out how to construct my Javascript classes (or singleton objects) correctly.

Существует большая разница между этими ("классами" и одноэлементными объектами). Ваша первая пара примеров - одноразовые объекты (синглтоны). Ваш третий (последний) пример создаетconstructor function это позволит вам создать несколько объектов с одним и тем же прототипом. Я бы посоветовалaugmenting 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
};

(Функции конструктора, как правило, начинаются с заглавной буквы.)

То, что вы используете (функция singleton или конструктор), зависит от того, что вам нужно.

Начиная с 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);
};

... именно поэтому вы привыкли видеть входящие библиотеки, такие как PrototypeClass вещи, или мои собственныеродословная; они устарели в синтаксисе 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 thetitle вашего вопроса:

What is the correct way to create a Javascript class?

Существует несколько одинаково правильных способов создания «классов». объектов в JavaScript, потому что JavaScript является очень гибким языком. Существуют стандартные функции конструктора "строитель" функции,Object.create (в средах с поддержкой ES5), что позволяет выполнять более прямое наследование прототипов и некоторые другие. Одна из замечательных особенностей JavaScript состоит в том, что вы можете выбрать свой стиль "class".

0

которая поддерживает ES5, вы можете сделать это:

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

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

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

var o=new O(0,0);
1

а не теоретическое, вам лучше использовать фреймворк.

Backbone.js has all you need, including mixins and an event system.

Если вам тоже нужны виджеты, подумайте

qooxdoo ExtJS

Оба они обеспечивают чистую архитектуру и могут использоваться без виджетов, но они требуют немного большего изучения, чем Backbone.

Структура наследования, предоставляемая этими средами, очень похожа на общую структуру на основе классов (например, Java). Это потому, что они создают специальные объекты внутри, которые просто служатprototypes для других, и, таким образом, взять на себя роль классов.

Например, когда вы звонитеExt.define('MyClass', {extend: 'ParentClass', mixins: foo, ... }), тогда Ext создаетfunction & Quot;MyClass& quot; и анонимный объект (MyClass.prototype) который содержит методы, которые вы предоставили.

Похожие вопросы