JavaScript自行执行匿名函数有哪些好的用例?

wil*_*ill 2 javascript theory

我理解自动执行匿名函数是什么,但我无法理解我将在何处使用它们以及为什么.这可能是因为我经常使用jQuery.你能提供好用例的例子吗?

jfr*_*d00 8

基本上,自执行匿名函数(在技术上更简称为IIFE或立即调用的函数表达式)与声明命名函数然后立即调用它相同.与IIFE的唯一区别在于它没有名称,因此它只能在原地执行(不是从其他地方调用),因此不会为当前名称空间添加名称.

所以,你可以使用一个任何时候,有一个函数内部一串代码将是有益的,当该代码永远只需要在当前定义的情况下被调用.

一些常见的地方:

  1. 在任何涉及一些局部变量和一些异步操作(ajax,timeout等等)的循环中,您希望在异步完成函数中为每个循环迭代分别访问这些局部变量.

  2. 要封装一些顶级代码,这些代码使用它自己的作用域运行一次,并拥有私有且与全局名称空间分离的本地变量.

  3. 要出于任何原因创建未命名的函数作用域.

例子:

循环索引(为每次调用分别冻结循环索引setTimeout()):

for (var i = 0; i < max; i++) {
    // capture the loop index into in a closure
    (function(index) {
        setTimeout(function() {
            console.log(index);
        }, 2000);
    })(i);
}
Run Code Online (Sandbox Code Playgroud)

顶级代码封装(创建不在全局范围内的私有但持久的变量):

(function() {
    var cntr = 0;
    window.getUniqueId = function() {
        return ++cntr;
    };
})();
Run Code Online (Sandbox Code Playgroud)

在代码中创建本地可用的快捷方式变量,否则将成为顶级范围.

function Dictionary(initialData) {
    // call parent constructor
    Set.apply(this, arguments);
}

(function() {
    // inherit from Set
    var proto = Dictionary.prototype = new Set();
    var base = Set.prototype;
    // Set constructor back to us
    proto.constructor = Dictionary;

    // override of the base class .add()
    // add(key, value)
    // add(Dictionary)
    // add({key1: value1, key2: value2})
    proto.add = function(arg1, arg2) {
        if (arg1 instanceof Set) {
            // call base class to just add another Set
            base.add.call(this, arg1);
        } else if (typeof arg1 === "object") {
            // cycle through the object and add all properties/values to the Set
            for (var prop in arg1) {
                if (arg1.hasOwnProperty(prop)) {
                    this._add(prop, arg1[prop]);
                }
            }
        } else if (typeof arg2 !== "undefined") {
            // must be add(key, value)
            this._add(arg1, arg2);
        }
        return this;
    }

    proto.get = function(key) {
        return this.data[key];
    }

    // See rest of code here: https://github.com/jfriend00/Javascript-Set/blob/master/dictionary.js

})();
Run Code Online (Sandbox Code Playgroud)

  • @zerkms - 如果操作全部是同步的,则不需要捕获循环索引,因为循环索引在同步回调中​​是有效的. (2认同)