Статические объекты / Литералы объектов
Статические объекты или литералы объектов не требуют создания экземпляра с помощью оператора new
и ведут себя как одиночные. Рассмотрим следующий пример:
Код:
var staticObject1 = {
a: 123,
b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);
Выход:
Object a=123 b=456 Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats
Обратите внимание, что изменение staticObject2.b
также затронуло staticObject1.b
. Однако это не всегда может быть желаемым эффектом. Многие библиотеки, такие как Dojo , предлагают метод клонирования объектов, который может облегчить эту ситуацию, если вы хотите сделать копию статического объекта. Продолжая предыдущий пример, рассмотрим следующее:
Код:
var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);
Выход:
Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats
Обратите внимание, что значения элементов staticObject1
и staticObject2
одинаковы, тогда как staticObject3
не подвержены изменениям этих других объектов.
Статические объекты также полезны для создания пространств имен проектов или библиотек, вместо того, чтобы заполнять глобальную область, и обеспечивают совместимость, как никто другой.
Это полезно при создании библиотек, которые требуют переносимости или совместимости. Это можно увидеть в популярных библиотеках, таких как Dojo, YUI и ExtJs, где все или большинство методов называются dojo.examplMethod()
, YUI().exampleMethod()
или Ext.exampleMethod()
соответственно.
Статические объекты также можно считать слабо аналогичными struct
в C / C ++.
Классовые Конструкторы / Созданные Объекты
Классы в JavaScript основаны на прототипном наследовании, которое является гораздо более сложным предметом и может быть прочитано о здесь , здесь и здесь .
В отличие от статических объектов, этот метод создания объекта предоставляет уникальную возможность для членов и методов объекта частной области действия из-за свойства closuer JavaScript. Рассмотрим следующий пример закрытых членов класса:
Код:
var SomeObject = function() {
var privateMember = "I am a private member";
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
};
var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();
Выход:
undefined string
I am a private member I am a public member
Обратите внимание, что typeof o.privateMember
"неопределен" и недоступен снаружи объекта, но находится изнутри.
Также можно создавать частные методы, но они не так просты, но все же просты в реализации. Проблема заключается в том, что значение this
внутри частного метода по умолчанию равно window
, и необходимо применить один из двух методов, чтобы гарантировать, что this
относится к объекту, с которым мы работаем, в данном случае, экземпляр SomeObject
. Рассмотрим следующий пример:
Код:
var SomeObject = function() {
var privateMember = "I am a private member";
var privateMethod = function() {
console.log(this.publicMember);
};
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod.call(this);
}
};
var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();
Выход:
undefined function function
I am a public member
Обратите внимание, что в рамках privateMethodWrapper()
, privatemethod
было выполнено с использованием call
и передачей this
для контекста функции. Это все хорошо; однако следующая техника предпочтительна (на мой взгляд), поскольку она упрощает область вызова и дает идентичные результаты. Предыдущий пример можно изменить на следующий:
Код:
var SomeObject = function() {
var self = this;
var privateMember = "I am a private member";
var privateMethod = function() {
console.log(self.publicMember);
};
this.publicMember = "I am a public member";
this.publicMethod = function() {
console.log(privateMember, this.publicMember);
};
this.privateMethodWrapper = function() {
privateMethod();
}
};
var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();
Выход:
undefined function function
I am a public member
Этот ответ послужил основой для поста в моем блоге , где я привожу дополнительные примеры. Надеюсь, это поможет;)