Создание объектов из закрытия JS: следует ли использовать "новое" ключевое слово?
я ответил на один вопрос о замыканиях здесь в SO с этим образцом:
function Constructor() {
var privateProperty = 'private';
var privateMethod = function(){
alert('called from public method');
};
return {
publicProperty: 'im public',
publicMethod: function(){
alert('called from public method');
},
getter: privateMethod
}
}
var myObj = new Constructor();
//public
var pubProp = myObj.publicProperty;
myObj.publicMethod();
myObj.getter();
//private - will cause errors
myObj.privateProperty
myObj.privateMethod
пользователь прокомментировал мой ответ, сказав:
Кроме того, если ваша функция явно возвращает объект, не рекомендуется называть его с помощью new, потому что это вводит в заблуждение - при использовании нового вы ожидаете, что результатом будет экземпляр конструктора
Я обычно создаю объекты с помощью new. но почему это не хорошая практика? это похоже на использование новых и не использование новых возвратов то же самое. Каков правильный способ создания объектов из замыканий?
Ответы
Ответ 1
Нет, это не одно и то же. Рассмотрим при использовании instanceof
:
function C1() {
return {};
}
function C2() {
}
var c1 = new C1();
var c2 = new C2();
alert(c1 instanceof C1); // false; wha...?
alert(c2 instanceof C2); // true, as you'd expect.
Вот демо.
Итак, создайте их, назначив this
, возможно, с защитой для предотвращения забытых new
s.
function Constructor() {
var privateProperty = 'private';
var privateMethod = function() {
alert('Called from private method');
};
this.publicProperty = "I'm public!";
this.publicMethod = function() {
alert('Called from public method');
};
this.getter = privateMethod;
}
Еще лучше используйте прототип, если это возможно:
function Constructor() {
var privateProperty = 'private';
var privateMethod = function() {
alert('Called from private method');
};
this.getter = privateMethod;
}
Constructor.prototype.publicProperty = "I'm public!";
Constructor.prototype.publicMethod = function() {
alert('Called from public method');
};
Ответ 2
Рассмотрим точку 4 из этого ответа: Что такое ключевое слово 'new' в JavaScript?
"Он возвращает вновь созданный объект, если функция-конструктор не возвращает не-примитивное значение. В этом случае это не-примитивное значение будет возвращено."
Так как функция C1 из ответа minitech возвращает пустой объект, переменная c1 будет возвращенным объектом, а не созданной оператором 'new'. Поэтому нет экземпляра функции конструктора.
Если я попытаюсь вернуть примитивное значение из функции конструктора, мой webstorm скажет мне: "Когда вызывается с новым, это значение будет потеряно и объект будет возвращен вместо этого".