JavaScript 立即执行函数表达式(IIFE)

立即执行函数表达式(IIFE,immediately invoked function expression)是一个立即执行的匿名函数表达式,它有两种写法:

;(function () {
  'use strict'
  // ...
})()

// or

;(function () {
  'use strict'
  // ...
} ())

// 上面两种都等价于命名函数
function sayHello() { ... }
sayHello()

// 你还在可以在 IIFE 中使用箭头函数
;(() => {})()

可以看到,立即执行函数有两个括号组成:一个括号用于包裹匿名函数(使其成为一个函数表达式),一个括号用于立即执行函数。

如果你看过一些很早之前的库,例如 JQuery 的源码,你应该知道下面这种情况:

+(function ($) {})(window.jQuery)

我们还可以向第二个括号添加一些参数,来作为匿名函数的参数,一旦 JavaScript 运行时对其求值,它就会立即被调用:

// IIFE
;(function (message) {
  console.log(message) // 'Hello World'
})('Hello World') 

// 使用命名函数的等价代码
function sayHello(message) {
  console.log(message)
}

sayHello('Hello World') // 'Hello World'

由于有些人习惯在语句结束后不加分号,如下面的 var a = 1 语句没有添加分号,所以该片段将报错。

// 出现错误的情况
var a = 1
(function () {
  console.log('Hello')
})()
// Uncaught TypeError: 1 is not a function

你应该在立即执行函数前添加分号或感叹号等,来避免在某些情况下出现 TypeError

// 所有这些都是等价的
;(function(){ console.log('Hello') })()
!(function(){ console.log('Hello') })()
+(function(){ console.log('Hello') })()
-(function(){ console.log('Hello') })()
~(function(){ console.log('Hello') })()
// ...

IIFE 通常用于创建一个独立的作用域,运行某些代码,同时将所有变量和函数保持在全局范围之外以避免冲突时使用。

它还常用于经典的闭包

for (var i = 1; i <= 10; i++) {
  ;(function (j) {
    setTimeout(function () {
      console.log(j)
    }, 1000)
  })(i)
}

// 额外的提示1:使用 ES6 的 let 或 const 可以轻松解决
for (let i = 1; i <= 10; i++) {
  setTimeout(function () {
    console.log(i)
  }, 1000)
}

// 额外的提示2:setTimeout 的第三个参数
for (let i = 1; i <= 10; i++) {
  setTimeout(function (i) {
    console.log(i)
  }, 1000, i)
}

IIFE 并都不是 JS 的规范,其为早期社区一些能人异士发现,并广泛推广。而现在有 ES6 的块级作用域、模块系统和 Transpiler 的兴起,IIFE 已经不在推荐使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值