【问题标题】:creating objects from JS closure: should i use the "new" keyword?从 JS 闭包创建对象:我应该使用“new”关键字吗?
【发布时间】:2012-03-07 10:47:00
【问题描述】:

我用这个示例在 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 返回相同的东西。从闭包创建对象的正确方法是什么?

【问题讨论】:

    标签: javascript closures


    【解决方案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.
    

    Here's a demo.

    因此,请改为通过分配给 this 来创建它们,可能还有防止忘记 news 的安全措施。

    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');
    };
    

    【讨论】:

    • 像这样:jsfiddle.net/DZTC8/1 都返回相同的东西,有或没有new
    • @Joseph:我的意思是它让instanceof 表现得很奇怪。返回的对象不是构造函数的实例,正如用户所期望的,而只是一个对象。
    • @minitech prototype 不是一个好的解决方案,因为您永远无法访问私人成员吗?
    • @jb10210:JavaScript 确实没有私有成员的概念,只有封闭变量。这取决于你需要做什么。如果你必须有私有变量,那么这些方法可以放在函数内部;但是您将无法直接拨打电话。这真的取决于。但在最后一部分,我说过“尽可能使用原型”——你会注意到 this.getter 仍然在构造函数中分配,因为它必须访问私有属性。 (据说是:))public方法只需要访问public属性即可。
    • @minitech 从现在开始我会在谈论 JS 时引用“私人会员”:) 感谢您的回复!
    【解决方案2】:

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

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

    因此,由于 minitech 的答案中的函数 C1 返回一个空对象,因此变量 c1 将是返回的对象,而不是由“new”语句创建的对象。因此没有构造函数的实例。

    如果我尝试从构造函数返回原始值,我的 webstorm 会告诉我:“当使用 new 调用时,此值将丢失,而将返回对象。”

    【讨论】:

      猜你喜欢
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      相关资源
      最近更新 更多