Skip to content

立即执行函数

IIFE(Immediately Invoked Function Expression)是一种定义后立即执行的函数。

1 关于错误Uncaught TypeError: (intermediate value)(...) is not a function

js
(function ($) {
    console.log($('div').html())
})(jQuery)


(function ($) {
    console.log($('h1').html())
})(jQuery);

ECMAScript规范具有分号自动插入规则,但是在上面代码中,在第一个立即执行函数末尾却不会插入,因为第二个立即执行函数,会被解释为如下形式:

js
(function ($) {
    console.log($('div').html())
})(jQuery)(function ($) {
    console.log($('h1').html())
})(jQuery);

可以在第一个立即执行函数的末尾添加分号来解决这个问题(也可以再立即执行函数开头添加分号):

js
(function ($) {
    console.log($('div').html())
})(jQuery);

(function ($) {
    console.log($('h1').html())
})(jQuery);

下面例子也会报上述错误

js
var num = 15
var fn1 = function (x) {
  if (x > num) {
    console.log(x)
  }
}

(function (fn) {
  var num = 100
  fn(30)
})(fn1)

解决办法如下

js
var num = 15
var fn1 = function (x) {
  if (x > num) {
    console.log(x)
  }
}; // 这里加上分号;

(function (fn) {
  var num = 100
  fn(30)
})(fn1)
js
var num = 15
var fn1 = function (x) {
  if (x > num) {
    console.log(x)
  }
}

// 或在立即执行函数前加上!、~
!(function (fn) {
  var num = 100
  fn(30)
})(fn1)

2 总结几种立即执行函数

立即执行函数使用了匿名函数,使用时可以向立即执行函数传参,立即执行函数使代码更加简洁,防止变量污染。

  • 无法表明函数与之后的()的整体性;在省略分号风格的代码中,容易出现类似Uncaught TypeError: (intermediate value)(...) is not a function 错误。所以不推荐使用这种方式。如果一个 js 文件中只有一个立即执行函数,使用这种方式也是可以的。

    js
    (function (arg){
      // ...
    })(argument);
  • 将匿名函数包裹在()或[]中

    js
    (function (arg){
      // ...
    }(argument)) // 向立即执行函数传入参数argument
    
    [function (arg){
      // ...
    }(argument)]
  • 使用~、!、+、-、void开头,结构清晰,不容易混乱,推荐使用

    js
    !function (arg){
      // ...
    }(argument)