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

Can someone explain this function-wrapping syntax in JavaScript?

本文关键字:函数 包装 语法 解释 JavaScript      更新时间:2023-09-26

我理解以下示例中变量范围的概念,但是有人可以解释函数包装语法(...)();,例如,您如何在实际的日常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
};

这种形式有几种方式很有用。一种是按词法限定一段代码的范围,以便其内部变量和方法与包含它的较大代码主体保持分离。通过这种方式,这是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( 将self = {}更改为 self = this 和 3( 选择性地删除末尾的return self转换为构造函数:

var Ret = function(){
    var self = this,
        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; // this is ignored by the compiler if used as a constructor
};
var ret = new Ret();
这是

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

JavaScript

有函数文字。它所做的只是使函数成为文字,并调用表达式的结果。这个名字让你感到困惑吗?所有名称将用于引用其自身内部的函数,并且它是可选的。(请注意,这与 IE 8 及更早版本不兼容。

与 C 中变量名具有块作用域不同,JavaScript(如 Pico(只有函数作用域。

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