Какой стиль вы используете для создания «класса»?

Есть несколько способов получить классоподобное поведение в javascript, наиболее распространенным является прототип, основанный на следующем:

function Vector(x, y, x) {
    this.x = x;
    this.y = y;
    this.z = z;
    return this;
}

Vector.prototype.length = function () { return Math.sqrt(this.x * this.x ... ); }

и подходы на основе замыкания, аналогичные

function Vector(x, y, z) {
    this.length = function() { return Math.sqrt(x * x + ...); }
}

По разным причинам последний работает быстрее, но я видел (и часто пишу) версию прототипа, и мне было любопытно, что делают другие люди.

9.08.2008 00:56:15
Мои тесты показали, что подход на основе замыкания медленнее. Вы должны создать отдельное закрытие для каждого объекта. Прототипный подход разделяет методы со всеми экземплярами.
Juan Mendes 20.01.2011 20:08:21
7 ОТВЕТОВ
РЕШЕНИЕ

Назначение функций прототипу лучше (для открытых методов), поскольку все экземпляры класса будут использовать одну и ту же копию метода. Если вы назначаете функцию внутри конструктора, как во втором примере, каждый раз, когда вы создаете новый экземпляр, конструктор создает новую копию функции длины и назначает ее только этому одному экземпляру.

Однако этот последний метод полезен, если вы хотите, чтобы у каждой копии была своя собственная копия, основное использование которой заключается в том, чтобы делать методы private / privileges, которые имеют доступ к закрытым переменным, объявленным внутри конструктора и унаследованным через механизм закрытия.

У Дугласа Крокфорда есть хорошее резюме .

10
9.08.2008 02:05:33

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

2
9.08.2008 01:12:26

У вас также есть выбор:

function Vector(x, y, z) {
  function length() {
    return Math.sqrt(x * x + ...);
  }
}

Что, вероятно, так же медленно, как во втором примере, но больше похоже на Java / C # и немного более явное.

2
9.08.2008 01:32:17

К счастью, я использую prototype.js , который предоставляет несколько хороших упаковщиков. Так что вы можете сделать это:

var Person = Class.create({
    initialize: function(name) {
        this.name = name;
    },
    say: function(message) {
        return this.name + ': ' + message;
    }
});

Prototype.js Документация: определение классов и наследования

3
24.07.2016 07:17:31
Я не думаю, что OP просил обертку, которая скрывает детали. Он хотел знать, почему вы выбрали бы тот или иной подход, чтобы он мог взвесить преимущества
Juan Mendes 20.01.2011 20:10:48

Существует также объектный буквальный подход к прототипу:

var Vector = function(){};

Vector.prototype = {
  init:function(x,y,z) {
    this.x = x;
    this.y = y;
    this.z = z;
  },
  length:function() {
    return Math.sqrt(x * x + ...);
  }
};

var v1 = new Vector();
v1.init(1,2,3);
5
7.02.2016 18:03:40
Вы не можете установить буквальный объект-прототип, если наследуете от чего-то другого, что переопределило бы предыдущий прототип
Juan Mendes 20.01.2011 20:08:51
Вы правы - но в этом случае «Вектор» - это новый объект, поэтому я не вижу необходимости беспокоиться о проблемах наследования
JayTee 25.01.2011 13:11:00

Я большой поклонник использования библиотеки Джона Резига для этого. Легкий, простой, и вы уже знаете, как его использовать, если вы знакомы с «обычным» объектно-ориентированным стилем.

1
26.07.2010 19:52:55

Там нет классов в JavaScript.

Однако есть объекты. Вам не нужен класс для создания объекта в JavaScript. У него есть функции конструктора, которые вы можете вызвать с помощью new, например:

var james = new Person();

Вы можете симулировать поведение класса как:

пример прототипа:

function Car (type) {
    this.type = type;
    this.color = "red";
}

Car.prototype.getInfo = function() {
    return this.color + ' ' + this.type + ' car';
};

пример буквального объекта

var car = {
    type: "honda",
    color: "red",
    getInfo: function () {
        return this.color + ' ' + this.type + ' car';
    }
}
1
11.11.2013 18:04:52