JavaScript Anonymous Constructor函数:!function(){}();

时间:2013-11-18 20:40:42

标签: javascript function constructor

我已经看到了这种在JavaScript中创建匿名构造函数的语法:

var Application = Application || {};
!function(window, Application) {
   Application.property = {/*...*/}
   Application.method = function(){/*...*/}
}(window, Application);

我想了解以下部分:

  1. 使用第一行(即var o = o || {};)与仅声明var o = (function(){})();有什么好处?
  2. 为什么在功能前使用!
  3. 当它们是全局对象时,为什么我会将windowApplication作为参数传递?
  4. 这是匿名构造函数最方便的方法吗?这比这更好:
  5. 4A)

     var Application = { 
        property: {},
        method: function(){}
     }
    

    或4b)

     var Application = (function() {
        var method = function(){/*...*/}
        return {method:method};
     }());
    

3 个答案:

答案 0 :(得分:0)

我不知道所有的答案,但我会尽力回答。

  1. 使用var Application = Application || {};只是意味着你正在处理范围。如果已经定义了“Application”变量,那么它只是意味着它继承并且现在在当前范围内可用。如果没有,“||” part(表示OR)表示它将被创建为空对象。您正在处理创建对象然后对其进行操作,而不仅仅是将结果重新生成。这就是为什么你不应该使用“o =(function(){...});”。然后“o”将是函数的结果,而不是对象的结果。

  2. 使用“!function”会将其视为表达式,但这可能很棘手,因为您可能需要在对立面思考。例如。 !null表示您正在检查它是否为空,而不是您要检查它是否为空。

  3. 传递窗口,Application对象再次处理范围。它显式地将它们传递给函数,然后在最后返回它们。把它想象成把衣服放在洗衣机里。你把它们放进去,可能会发生一些事情,然后你就把它们拿回来了。这是一个非常粗略的想法,并不是最好的例子,但这是我一段时间以来的想法。你把衣服放入,然后打电话,然后冲洗功能,然后用肥皂功能,然后再次冲洗,然后旋转排水。

  4. 希望其他人可以回答这个问题,我不确定区别是什么。

答案 1 :(得分:0)

第一行是确保Application始终存在,并且通常用于预期Application已经存在的情况,并且该函数仅增加现有对象。如果它不存在,这可以确保我们不会因访问undefined属性而出错。您的示例仅在Application尚不存在的情况下等效。在所有其他情况下,您的代码将删除现有的Application,这几乎肯定不是意图。

Vatev的评论解释了!的作用。这是使有问题的函数成为自执行匿名函数的另一种语法。 (顺便提一下,它还需要函数的返回值 - 当前为undefined,并且翻转它的真实性,因此它的结果为真。因为结果没有存储在任何变量中,但显然不是目的。)

最后,为什么要将windowApplication传递给函数并在那里使用它?这是一项安全功能,以防其他代码稍后更改windowApplication。它保证在匿名函数中,windowApplication正是您所期望的。在您给出的简写示例中,这似乎无关紧要 - 毕竟,如果您立即使用它们并且不存储它们,为什么要保护这些变量?在许多情况下,您从此函数返回一些内容,然后windowApplication将存储在闭包中,因此您将保留变量。它使以后决定说Application = {...}的人安全。

答案 2 :(得分:0)

由于到目前为止两个答案忽略了这两个细节:像jQuery这样的库使用的模式使用以下两个参数:

(function (window, undefined) {
    window.myPlugin = ...;
})(window);

这里有两件事:

  • undefined被指定为参数,但未被传入。这样,undefined保证在内部范围内具有预期值。这只适用于允许覆盖undefined的旧浏览器(尽管这样做一直被认为是不好的做法 - 这就像jQuery这样的库可以避免其他代码干扰他们的代码)。

    < / LI>
  • 在范围内对window之类的全局对象进行别名化可以使代码更加缩小(也适用于undefined)。显然,对别名对象的引用越多,保存的就越多:

(function(w,u){w.myPlugin=...;w.somethingElse=...;if(whatever===u){return;}})(window);

相比
(function(){window.myPlugin=...;window.somethingElse=...;if(whatever===undefined){return;}})();

window你不会节省太多钱,因为通常你不想把全局物体弄得乱七八糟。但是别名undefined可以为你节省很多空间。