【问题标题】:Are these two ways of constructing an object in JavaScript equivalent?这两种在 JavaScript 中构造对象的方式是等价的吗?
【发布时间】:2011-04-20 17:14:56
【问题描述】:

给定:

    function A(name) {
        this.name = name;
    }

是:

    var a1 = new A("A1");

完全等同于:

    var a1 = {};
    A.call(a1, "A1");
    a1.__proto__ = A.prototype;

?

谢谢

【问题讨论】:

    标签: javascript


    【解决方案1】:

    嗯,__proto__ 是非标准的 (link) 并且不是所有实现都支持的问题。 :-) 除此之外,constructor 属性 (link) 设置不正确,您可能必须自己做。另外,我认为您最好在调用构造函数之前设置原型。所以:

    function A(name) {
        this.name = name;
    }
    
    var a1 = {};
    a1.__proto__ = A.prototype;
    a1.constructor = A; // <=== Added this bit
    A.call(a1, "A1");   // <=== Moved this down
    

    不过,至少在支持__proto__ 的实现上很接近。我不会打赌它完全一样。值得阅读 ECMAScript 第 5 版规范以了解更多详细信息,特别是第 11.2.2 节“new 运算符”和第 13.2.2 节“[[Construct]] ”。

    一些不支持__proto__ 的实现可能支持第5 版规范(第15.2.3.5 节)定义的新Object.create 函数,它允许您创建具有特定原型的对象。在支持Object.create 的实现中,创建a1 的代码如下所示:

    var a1 = Object.create(A.prototype);
    a1.constructor = A;
    A.call(a1, "A1");
    

    卷起来,然后:

    function A(name) {
        this.name = name;
    }
    
    if (typeof Object.create === "function") {
        a1 = Object.create(A.prototype);
    }
    else if ({}.__proto__) {
        a1 = {};
        a1.__proto__ = A.prototype;
    }
    else {
        /* Fail */
    }
    a1.constructor = A;
    A.call(a1, "A1");
    

    ...但这完全未经测试,而且,我不会指望它完全完全相同,除非确实仔细阅读规范。

    当然,只要有可能,如果您正在处理构造函数,我建议您以正常方式使用它。不过,像 __proto__Object.create 这样的高级工具对于进行纯原型继承(不需要构造函数)很有用。

    【讨论】:

      猜你喜欢
      • 2015-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 2013-02-24
      相关资源
      最近更新 更多