乐趣区

关于javascript:JavaScript-立即执行函数

立刻执行函数,顾名思义,即创立后被立即执行的函数。在理论工作中,立刻执行函数并不是必须用到的语法,不过应用立刻执行函数有个益处是可能简化代码。

立刻执行函数语法

在 JavaScript 中一个一般的函数定义语法如下:

function foo() {console.log(123);
}

如果要调用这个函数,那么咱们会执行:

foo();

如果把它改成立刻执行函数的写法是这样的:

(function foo() {console.log(123);
}());

或者这样的:

(function foo() {console.log(123);
})();

以上两个立刻执行函数相当于 函数申明 + 函数调用。一个一般的函数申明须要应用 function 关键字,函数调用须要应用函数名加一个圆括号(foo())。咱们晓得函数名实际上保留了函数的援用,所以 foo 变量保留了 foo 函数体的援用,因而实践上立刻执行函数的写法能够是这样:

function foo() {console.log(123);
}();

然而如果这样写,JavaScript 解释器会报 SyntaxError 语法错误。所以就须要用一个括号把整个函数括起来再进行调用。用来调用函数的括号能够写在把函数括起来的括号的外面或者里面,两种写法没有任何区别,抉择一个你更能接管的写法即可。

立刻执行函数特点

立刻执行函数和一般函数简直没什么差异,既能接管参数、也能有返回值,但它们之间还是有一个十分不一样的中央,就是立刻执行函数执行完后就立即被销毁。

咱们下面定义了一个 foo 函数,如果想屡次执行,那么只须要屡次调用 foo() 即可:

function foo() {console.log(123);
}

foo();
foo();
foo();

然而,如果是立刻执行函数,屡次调用 foo() 将失去异样。

(function foo() {console.log(123);
})();

foo();  // ReferenceError: foo is not defined

能够看到在第二次调用 foo() 函数时,会失去 foo is not defined。即 foo 函数实际上曾经被销毁了。所以咱们在定义立刻执行函数的时候,通常不须要指定函数名,定义一个匿名函数即可:

(function () {console.log(123);
})();

立刻执行函数应用场景

立刻执行函数执行一次就被销毁,所以如果咱们定义了一个函数只被执行一次的时候就能够将其换成立刻执行函数。

立刻执行函数比拟常见的两个应用场景是:

  1. 数据初始化
  2. 解决闭包中援用循环变量的问题

对于数据初始化比拟好了解,如想要计算 num 的值:

var num = (function (a, b) {return a + b;})(1, 2);

而对于如何解决闭包中援用循环变量的问题,咱们须要看一个略微简单一点的例子:

function foo() {var arr = [];
    for (var i = 0; i < 3; i++) {arr.push(function bar() {return i * i;});
    }
    return arr;
}

var result = foo();
result[0]();  // 9
result[1]();  // 9
result[2]();  // 9

以上示例代码中,闭包中的 bar 函数援用了其内部的循环变量 i,咱们原本期待的后果是 014,但实际上最终后果都为 9

呈现此问题的起因是 for 循环不具备独立的块级作用域导致的,此时就能够应用立刻执行函数来解决这个问题。

function foo() {var arr = [];
    for (var i = 0; i < 3; i++) {arr.push((function (j) {return function bar() {return j * j;}
        })(i));
    }
    return arr;
}

var result = foo();
result[0]();  // 0
result[1]();  // 1
result[2]();  // 4

咱们在 bar 函数的内部,定义了一个立刻执行函数,这样,在每次循环时,以后循环变量 i 的值都被传递到了函数外部的 j 变量,所以能失去咱们想要的后果。

其实还有一种更简略的解决办法,间接将申明循环变量 i 的关键字 var 改为 let 也能同样达到成果,读者能够自行尝试。

立刻执行函数摸索,审慎尝试

我在下面举了一个应用立刻执行函数初始化数据的例子:

var num = (function (a, b) {return a + b;})(1, 2);

其实这种写法不应用括号把函数包起来也是能够的:

var num = function (a, b) {return a + b;}(1, 2);

同样能失去正确的后果,并且 JavaScript 解释器并没有报错。

实际上,在执行赋值操作的时候,下面的代码曾经变成了一个表达式,而 JavaScript 解释器认为 函数表达式 是能够间接被执行的。

所以上面的代码也可能被正确执行:

+function () {console.log(123);
}();

-function () {console.log(123);
}();

留神这里的 +- 代表正、负,并不是加、减。JavaScript 有相当多的这种比拟鬼畜的写法,并不倡议大家在理论工作中应用,仅供娱乐。

首发地址:https://jianghushinian.cn/

退出移动版