Утверждения являются комментариями, которые не становятся устаревшими. Они документируют, какие теоретические состояния предназначаются, и какие состояния не должны происходить. Если код изменяется так состояния, позволенные изменение, разработчику скоро сообщают и должен обновить утверждение.
Статические объекты или объект литералы, не требуют создания экземпляра с помощью оператора 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
Обратите внимание, что withing privateMethodWrapper ()
, privatemethod
был выполнен с использованием вызова
и передачи в это
для контекста функции. Все в порядке; однако следующий метод предпочтительнее (на мой взгляд), поскольку он упрощает область вызова и дает идентичные результаты. Предыдущий пример можно изменить на следующий:
Код:
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
Этот ответ лег в основу сообщения в моем блоге , где я привожу дополнительные примеры. Надеюсь, что это поможет;)
Разница в том, что объект thing1
связан с классом thing1
и унаследует (не буквально) thing1
] prototype.
Например, позже вы можете написать
thing.prototype.initAndSend = function() { this.init(); this.send(); };
После этого вы сможете написать thing1.initAndSend ()
без изменения thing1
. Кроме того, thing1.constructor
будет равен методу thing
, тогда как {}. Constructor
будет равен Object
.
] Между прочим, по стандартному соглашению имена классов пишутся с заглавной буквы.
Функции - это объекты, а также конструкторы (их можно создать с помощью new
).
Хеш-таблицы / объекты ( {}
) являются не могут быть созданы, поэтому они обычно используются в качестве структур данных. И я не уверен, разумно ли называть их «Объектами».
В первом методе вы объявляете один объект. Во втором случае вы объявляете класс, из которого можно создавать (т.е. создавать) множество различных копий.
Случай 2 ссылается на конструкторы классов javascript . Различие заключается в том, что переменная еще не является объектом, поэтому вы не можете ссылаться на thing1.sanity. Вам нужно будет инициализировать класс, создав экземпляр указанного класса перед вызовом любых внутренних членов:
var myConstructor = function() {
this.sanity = 0;
}
// wont work
alert(myConstructor.sanity);
// works
var thing1 = new myConstructor();
alert(thing1.sanity);
Вот статья, которая идет дальше моего быстрого примера: