有人可以在JavaScript中解释这个函数包装语法吗?

时间:2012-04-28 03:49:46

标签: javascript syntax

我理解以下示例中的变量范围的概念,但有人可以解释函数包装语法 (...)();,例如:你如何在日常的JavaScript编程中使用它?这不是我从PHP / Java / C#中知道的。

window.onload = function() {
    var i = 4;
    console.log(i); //4
    (function showIt() {
        var i = 'whatever';
        console.log(i); //whatever
    })();
    console.log(i); //4
};

4 个答案:

答案 0 :(得分:2)

这是定义一个类似于您已经熟悉的函数showIT(使用function showIT() {...})。最后的()直接调用与定义相同的行中的函数。这可能是你不熟悉的部分。就像你说showIT()来调用函数一样,你可以用实际的定义替换名称,它也可以在Javascript中使用。

答案 1 :(得分:2)

这种形式有多种用途。一种是在词法上对一段代码进行范围调整,以使其内部变量和方法与包含它的较大代码体分开。通过这种方式,它是JavaScript进行块作用域的方式。但我使用这种格式的最常见方式是替代它:

var ret = {
    depth:0,
    initialized:false,
    helper:function() { /*help with some stuff*/ },
    initialize:function(){ /*do some initialization code*/ },
    action:function(){/*do the thing you want*/}
    destroy:function() { /*clean up*/ }
}

对于这种格式绝对让我失望的是找到丢失的大括号和逗号是非常耗时的。例如,上面的代码不起作用,因为在action声明的末尾没有逗号,除非我指出它,否则你很难找到问题,因为抛出异常时,它是在整个声明中引发的,而不是“导致问题”的部分。这是一个可预测的问题,如果我可以避免它,我就不再使用这种格式了。我拒绝。相反,可以更清楚地写出相同的内容:

var ret = (function(){
    var self = {},
        initialized = false;

    var helper = function() { /*help with some stuff*/ };

    self.depth = 0;
    self.initialize = function() {/*do some initialization*/};
    self.action = function() {/*do the thing you want*/};
    self.destroy = function() { /*clean up*/ };

    return self;
}());

对我来说有两大优势。一个,丢失的大括号和逗号可以更容易找到(当抛出异常时,行号将接近它缺少的区域)。第二,你可以选择将一些变量和方法保密,你可以保留第一块代码的所有好处。

我将为此格式提供的最后一个插件是上面的代码(有点像Singleton)可以通过1)删除外部的调用括号来转换为构造函数,2)更改{{ 1}}到self = {},以及3)可选择删除最后的self = this

return self

答案 2 :(得分:0)

JavaScript具有函数文字。它所做的只是创建一个函数文字,并调用表达式的结果。这个名字让你感到困惑吗?所有名称都将用于指代其自身体内的函数,并且它是可选的。 (请注意,这与IE 8及更早版本不兼容。)

答案 3 :(得分:0)

与变量名具有块范围的C不同,JavaScript(如Pico)只有函数范围。

因此,如果您想创建一个新的名称范围,就不能像在C中那样使用{ ... },您必须使用(function() { ... })();