Javascript "классы" (без рамок) - PullRequest
3 голосов
/ 17 мая 2009

Я делаю свой первый проект JavaScript, который интенсивно использует объекты. Из-за того, как это работает, почти все пользовательские объекты сделаны так:

namespaceobj = {};
namespaceobj.subobject = {};
namespaceobj.subobject.somefunction = function(arg, uments) {
    // Do Stuff
}
namespaceobj.subobject.somedata = 10;
namespaceobj.othersubject = {};
namespaceobj.othersubject.somefunction = function(some, args) {
    // Do more stuff
}
// More subobjects etc.

Это нормально, поскольку все пользовательские объекты в любом случае имеют только один экземпляр (примерами подобъектов являются пользовательский интерфейс, инструменты, общие данные и т. Д.).

Однако я видел, что код делал что-то вроде этого (синтаксис, вероятно, неправильный, это просто память того, что видел похожий код)

function SomeClass() {
    this.somedata = 42;
    this.somefunction = function(a, few, args) {
        // Do Stuff
    }
}
// More classes and stuff
// Elsewhere:
someInstance = new SomeClass(); // AFA I recall, new was optional
someInstance.somefunction();

Может ли кто-нибудь объяснить, как работают "классы" во втором примере, и любые подводные камни, с которыми я могу столкнуться при их использовании.

Ответы [ 4 ]

2 голосов
/ 17 мая 2009

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

Я бы посоветовал вам прочитать JavaScript и объектно-ориентированное программирование (ООП) :

JavaScript - отличный язык для написать объектно-ориентированный веб Приложения. Может поддерживать ООП потому что он поддерживает наследование через прототипирование, а также свойства и методы. Много разработчики отбросили JS как подходящее ООП язык, потому что они так используются в стиле класса C # и Java. Многие люди не осознают этого JavaScript поддерживает наследование. когда вы пишете объектно-ориентированный код это мгновенно дает вам силу; вы можете написать код, который можно использовать повторно и это инкапсулировано.

2 голосов
/ 17 мая 2009

Я думаю, что синтаксис, о котором вы думали, выглядит следующим образом: -

function SomeClass() {
    var somedata = 42;
    this.somefunction = function(a, few, args) {
    // Do Stuff like:-
    return somedata + a;
  }
}
// More classes and stuff
// Elsewhere:
someInstance = new SomeClass(); // AFA I recall, new was optional
someInstance.somefunction(15);  //returns 57

Функция, которая назначена некоторой функции, создается в Контексте выполнения , который возникает при выполнении функции (в этом случае SomeClass () выполняется как часть новой операции, которая назначена для someInstance). Функции могут обращаться к переменным, которые являются частью контекста выполнения, в котором они созданы, поэтому в этом случае somedata является переменной, к которой у somefunction есть доступ.

Этот подход фактически делает некоторые данные частным состоянием объекта, поскольку только функции, созданные внутри тела функции SomeClass, могут получить к нему доступ.

Это упрощение, вам следует сначала изучить Javascript без ссылки на OO-программирование, узнать о цепях областей действия и цепях прототипов . Когда вы поймете это, вы сможете лучше понять количество различных подходов к реализации ОО-дизайна в Javascript и какой подход лучше всего соответствует вашим потребностям.

0 голосов
/ 17 мая 2009

Вторая форма, возможно, является лучшей формой, потому что она создает «Класс», который имеет множество функций, живущих на своем прототипе. Когда новый класс создается, новый экземпляр также получает свой прототип, установленный на то же самое. В примере класса функции живут по прототипу.

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

Прототипы предпочтительнее, потому что это означает, что работа по определению «класса» выполняется только один раз. Все экземпляры имеют один и тот же прототип - поэтому можно получить мощные конструкции, такие как добавление / изменение / удаление функций, и все экземпляры увидят изменения. В первом примере вы указываете, что все они являются независимыми объектами, где можно изменить что угодно в любом случае независимо.

В конце концов, все объекты Javascript являются хеш-таблицами свойств и функций. Когда кто-то обращается к объекту через «object.something», все является значением, включая функции. Однако, когда используется обозначение вызова функции «object.foo (...)», среда выполнения пытается найти «foo» для «объекта». Если среда выполнения не может найти «foo» на «объекте», она попытается найти «foo» на прототипе «объекта». Это продолжается до тех пор, пока что-то не будет найдено или больше не останется прототипов.

Затем среда выполнения попытается вызвать передаваемые параметры «foo» и т. Д. Естественно, что вещи взрываются, если foo не функция.

0 голосов
/ 17 мая 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...