两种JavaScript对象类型之间的差异

时间:2012-04-19 14:23:11

标签: javascript prototype

我看到JavaScript中的对象最常用以下两种方式组织。有人可以解释两者之间的区别和好处吗?是否存在一个更适合另一个的情况?

真的很感激任何澄清。非常感谢!

首先:

   var SomeObject;

    SomeObject = (function() {

     function SomeObject() {}

         SomeObject.prototype.doSomething: function() {

         },
         SomeObject.prototype.doSomethingElse: function() {

         }

    })();

第二

SomeObject = function() {

 SomeObject.prototype.doSomething: function() {

 },
 SomeObject.prototype.doSomethingElse: function() {

 }

}

3 个答案:

答案 0 :(得分:5)

这两个例子都不正确。我想你的意思是:

首先:

var SomeObject;
SomeObject = (function() {

    function SomeObject() {
    }

    SomeObject.prototype.doSomething = function() {
    };

    SomeObject.prototype.doSomethingElse = function() {
    };

    return SomeObject;

})();

(注意匿名函数末尾的返回,=而不是:的使用,以及分号来完成函数赋值。)

或者你的意思是:

function SomeObject() {
}

SomeObject.prototype.doSomething = function() {
};

SomeObject.prototype.doSomethingElse = function() {
};

(没有匿名封闭功能。)

第二

function SomeObject() {
}
SomeObject.prototype = {

    doSomething: function() {
    },
    doSomethingElse: function() {
    }
};

(请注意,原型的分配是之外的SomeObject函数;在这里,我们使用:,因为我们在对象初始化器中。我们再次拥有最后的;来完成赋值语句。)

如果我是对的,那么它们之间的区别就很小了。它们都创建了一个SomeObject构造函数,并为其原型添加了匿名函数。第二个版本用一个全新的对象(我不推荐)替换 SomeObject构造函数的原型,其中第一个版本只是增加SomeObject构造函数的原型。已经有了。

更有用的形式是:

var SomeObject;
SomeObject = (function() {

    function SomeObject() {
    }

    SomeObject.prototype.doSomething = doSomething;
    function doSomething() {

    }

    SomeObject.prototype.doSomethingElse = doSomethingElse;
    function doSomethingElse()
    }

    return SomeObject;

})();

在那里,我们分配给doSomethingdoSomethingElse的函数有名称,这在您在调试器中浏览代码时很有用(它们显示在调用堆栈,断点列表等)。包含所有内容的匿名函数存在,以便doSomethingdoSomethingElse名称不会污染封闭的名称空间。更多:Anonymouses anonymous

我们中的一些人更进一步:

var SomeObject;
SomeObject = (function() {
    var p = SomeObject.prototype;

    function SomeObject() {
    }

    p.doSomething = SomeObject$doSomething;
    function SomeObject$doSomething() {

    }

    p.doSomethingElse = SomeObject$doSomethingElse;
    function SomeObject$doSomethingElse()
    }

    return SomeObject;

})();

...因此,我们不仅会在列表中看到doSomething,还会看到SomeObject$doSomething。但有时可能会妨碍它,这是一种风格选择。 (另请注意,我使用匿名函数来包含SomeObject.prototype的别名,以减少输入。)

答案 1 :(得分:0)

首先,两个代码段都不会为我解析(Chrome) - 您应该使用=代替:。那就是说,我的拙见随之而来。

后一个片段有点奇怪,因为你实际上是在构造对象时在SomeObject的原型上定义方法,而不是在解析时。因此,如果您在SomeObject.prototype上重新定义了某个方法,则在构造新对象后,它将恢复为原始版本。这可能会导致此类现有对象出现意外行为。

前一个看起来很好,除了(function { ...} ())()包装器可能没有必要。你可以声明:

function SomeObject() {}
SomeObject.prototype.doSomething = function() {}
SomeObject.prototype.doSomethingElse = function() {}

答案 2 :(得分:0)

问题中第一个和第二个之间的实际差异只是:

var o = (function () {})();  # call this (A)

var o = function () {};  # call this (B)

不幸的是,你提供的示例中没有都是正确编写的,虽然我不认为其中任何一个实际上会在分析时发出错误,但两者都会以有趣的方式打破你试着用结果做事。

为了给出(A)和(B)之间差异的答案,(A)是即时功能应用模式。 JavaScript Patterns一书有a good discussion,我推荐。

在我写这篇文章时,其他人已经解释了代码中的实际问题。特别是T.J.克劳德指出了重要的事情。