为什么要自行执行匿名函数

时间:2013-11-22 10:09:39

标签: javascript anonymous-function

今天我来了一个自我执行功能,而不是以某种方式我最终了解 自我执行匿名函数,然后我读过这篇文章:http://briancrescimanno.com/how-self-executing-anonymous-functions-work/

我不知道为什么使用自我执行匿名函数因为我需要做类似的事情:

var test = "a";
(function(foo) {
    alert(foo);
})(test);

我可以做类似的事情:

var test = "a";
alert(foo);

或者我错过了什么?

这也可以对函数内部的任何代码进行,但是我使用alert()来制作简单的


更新

即使我已经接受并回答我想分享一些我发现的东西,如果有人后来遇到这个问题的话:)

使用这种表示法,我们也可以制作如下的无限循环:

(function loop(){
    // do something here
    loop();
)();

4 个答案:

答案 0 :(得分:4)

为什么要使用IIFE有几个原因:

1)不乱扔垃圾

var a = 'foo';
alert(a);

VS

(function() {
  var a = 'foo';
  alert(a);
}())

两个示例都做同样的事情,但在第二个示例中,外部范围内没有变量。

2)状态捕获

var a = 'foo';
window.setTimeout(function() { alert(a); }, 1);
a = 'bar';

VS

var a = 'foo';
window.setTimeout( (function(a_copy) { 
    return function() { alert(a_copy); }
  }(a)), 1);
a = 'bar';

第一个示例提醒bar,第二个示例提醒foo。你会发现这种技术特别适用于循环。

答案 1 :(得分:2)

您描述的语法通常称为“立即调用的函数表达式”,或IIFE。

其中一个常见用例是模拟私有变量:

var ns = (function () {
    var x = 1; // "private"
    return {
        getX: function () {
            return x;
        }
    }
}());
ns.getX(); // 1
ns.x; // undefined because x is "private"

在该示例中,x变量是IIFE的本地变量。它不能直接在它外面访问。但是,由于getX方法引用了它, 可以在IIFE之外访问(因为它是返回对象的一部分),对x的引用保持活动状态。这就是术语“封闭”的意思。

答案 2 :(得分:1)

如果您只是在alert内部执行,自执行功能并不是真正有用。

考虑这样的事情:

(function(foo) {
    var a = ..
    // do something with a and foo
})(test);

这里的优点是a是"私人"在方法内部并不能在方法之外使用。因此a不会以全局变量结束,也不能被其他使用同名变量的javascript覆盖。

答案 3 :(得分:1)

你的初始例子不值得在匿名函数中执行,所以它是一个不好的例子来理解为什么要使用这种技术。这是探索状态捕获的一个很好的例子:

var list = [{id: 1, data: null}, ...];

for (var i = 0; i < list.length; i++) {
  (function(item) {
    // start async request, for each item in the list, in the order of the list
    asyncAjax("get-data-from-somewhere.json?what=" + list[i].id, function (response) {
      // thats the on success callback, which gets executed when the server responded
      // each item will have different response times, therefore the order of response is various
      // if we would use simply list[i].data, it wouldn't work correctly, because "i" would has the value of list.length, because the iteration has been finished yet.
      item.data = response;
    });
  })(list[i]);   // the function will preserve the reference to the list item inside, until the function has been fully executed
}

写同步时。代码,你总是可以回退到经典的面向对象的结构代码风格。所以你可以避免闭包/即时匿名函数调用。但是只要你使用异步。机制,闭包变得非常方便,使你的代码看起来更干净,当然只有你能阅读和理解闭包:)

顺便说一下,你也可以写一下:

function(private) {}(outer)

相同
(function(private) {})(outer)

但第二个更好,因为它对读者来说更为明显。