0

我仍然对那些立即调用函数表达式感到有些困惑。我得到了范围关闭(我读过 Crockford 的书),但后来@plalx 好心给我写了这个例子,因为我有另一个疑问(jsfiddle 在最后链接)使用 IIFE。这又让我有点困惑,这就是我的想法。

在 Java 中,人们会认为:

type doSome(type input){
do_stuff
return same type
};

然后稍后

doSome(data);

所以在 js 中我可以做同样的事情,对吧?

function doSome(input){
do_stuff;
return someThing;
}

后者:

doSome(data);

或者更常用的 IIFE:

var doSome = (function(data){
do_stuff;
return something
})();

后者:

doSome(data);

到目前为止我是正确的吗?

所以我的问题是:为什么在这种情况下使用 IIFE 而不是其他方式?提出这种疑问的两个代码都在 jsfiddle 中:

http://jsfiddle.net/Victornpb/PT6Xc/7/

http://jsfiddle.net/PT6Xc/8/

4

2 回答 2

2

这两个示例之间的主要区别在于函数主体的评估频率。

在这个例子中:http://jsfiddle.net/Victornpb/PT6Xc/7/,使用 IIFE,里面的代码只被评估一次并返回函数。当您通过

document.body.innerHTML = deaccentuate(s);

它只执行返回的函数体,而不执行它之前的语句。

在另一个例子中:http: //jsfiddle.net/PT6Xc/8/

每次运行函数时都会评估函数的整个主体deaccentuate(s)

document.body.innerHTML = deaccentuate(s);

因此,如果您有一些繁重的操作只想在运行时执行一次,或者像@RobG 对私有成员所说的那样,在这种情况下使用 IIFE。

您可以通过添加console.log("whatever")到两个示例的顶部进行验证来验证这一点。

http://jsfiddle.net/PT6Xc/9/ -> 与 /7/ 一起使用

http://jsfiddle.net/PT6Xc/10/ -> 与 /8/ 一起使用

于 2013-10-17T00:44:43.047 回答
2

IIFE 对于使用闭包来保存对“私有”变量的引用很有用。它们可能用于防止其他人修改您想要保护的值,或者保存只需要执行一次(或偶尔)但函数经常使用的计算结果。

例如,要获取您可能编写的元素的文本:

function getText(el) {

  if (typeof el.textContent == 'string') {
    return el.textContent;

  } else if (typeof el.innerText == 'string') {
    return el.innerText;
  }
}

但是为了避免每次都进行测试,可以使用 IIFE 并且只执行一次测试:

var getText = (function() {
  var d = document.createElement('div');

  if (typeof div.textContent == 'string') {
    return function (el) {
      return el.textContent;
    };

  } else if (typeof div.innerText == 'string') {
    return function (el) {
      return el.innerText;
    };
  }
}());

所以测试只进行一次。您还可以使用类似的策略保留对全局对象的引用:

var someFn = (function (global) {

    // in here, you are certain that global references the global object

    return function() {
      // and in here too
    };

// And here's where it comes from
}(this));
于 2013-10-17T00:13:31.100 回答