создание объектов из JS замыкания: я должен использовать ключевое слово "new"? - PullRequest
13 голосов
/ 16 февраля 2012

Я ответил на один вопрос о замыканиях здесь, в 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, вы ожидаете, что результат будет экземпляром Constructor

Я обычно создаю объекты, используя new . но почему это не хорошая практика ? похоже, что использование new и не использование new возвращает одно и то же. Как правильно создавать объекты из замыканий?

Ответы [ 2 ]

11 голосов
/ 16 февраля 2012

Нет, это не одно и то же. Учитывайте при использовании 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 с.

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 голосов
/ 19 ноября 2015

Рассмотрим пункт 4 из этого ответа: Что такое ключевое слово "new" в JavaScript?

"Возвращает вновь созданный объект, если функция конструктора не возвращает не примитивное значение. В этом случае будет возвращено это не примитивное значение. "

Таким образом, поскольку функция C1 из ответа minitech возвращает пустой объект, переменная c1 будет тем возвращаемым объектом, а не тем, который создан 'new'заявление.Поэтому нет экземпляра функции конструктора.

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

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