从JS闭包创建对象:我应该使用“new”关键字吗?

时间:2012-02-16 02:02:35

标签: javascript closures

我在这里用一个样本回答了关于闭包的一个问题:

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,您希望结果是构造函数的一个实例

我通常使用 new 创建对象。但为什么不是一个好的做法?似乎使用new而不使用new返回相同的东西。从闭包创建对象的正确方法是什么?

2 个答案:

答案 0 :(得分:11)

不,这不是一回事。使用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.

Here's a demo.

相反,请通过指定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');
};

答案 1 :(得分:2)

从这个答案中考虑第4点:What is the 'new' keyword in JavaScript?

"它返回新创建的对象,除非构造函数返回非原始值。在这种情况下,将返回该非原始值。"

因此,当minitech的回答中的函数C1返回一个空对象时,变量c1将是返回的对象,而不是由' new'创建的对象。声明。因此没有构造函数的实例。

如果我尝试从构造函数返回一个原始值,我的webstorm告诉我:"当用new调用时,这个值将丢失,而对象将被返回。"