立即调用的函数表达式(IIFE)

本文详细解析了JavaScript中立即调用的函数表达式(IIFE)的概念,包括其作用于区别、常见写法如圆括号包裹、不加括号的限制,以及在模块封装、事件处理等场景的应用实例。通过阮一峰教程和实际例子阐述了如何避免函数提升并创建私有变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

爱总结,爱搬砖,爱生活

引言

偶然之间看到一个问题,问题是这样的:

(function() {}());
(function() {})();

上面这两种写法有没有什么区别?
打眼一看这个问题不太好回答,这说明了一个问题,我对这类立即调用的函数表达式还不熟悉,这个时候应该去百度看看大家怎么理解立即调用的函数表达式。

心得

  • 立即调用的函数表达式(在这之前我一直称呼它为立即执行函数,经过此番探索更正了之前不合理的叫法)
  • 立即调用的函数表达式的作用:
    • 不必为函数命名,避免污染全局作用域;
    • 立即调用的函数表达式内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量和方法。

回顾

先从函数的定义和使用说起

// 函数声明
function foo() {
      console.log('foo')
}

// 函数表达式
var bar = function() {
  console.log('bar')
}

// 调用
foo()
bar()
  • 上述两种方式是开发中常用的函数定义和调用方式,回忆一下这两种定义函数的方式;
    • 函数声明是会发生函数提升的,允许在定义之前使用
    • 函数表达是不会发生函数提升,是不允许在定义之前使用的,函数表达是可以是一个匿名函数(上面这样的),也可以是一个命名函数(下面这样)
    // 函数表达式
    var rn = function rn() {
      console.log('rn')
    }
    
  • 关于函数定义的回顾到此为止,接下来探究立即调用的函数表达式

立即调用的函数表达式

  • 文章开头给出的两种写法
(function() {}());
(function() {})();
  • 要知道这两种写法有没有区别,那就得先弄清楚为什么会这样写,添上一对括号的作用是什么?不加这对括号可不可以?

括号的作用

函数定义后立即调用的解决方法,就是不要让function出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面。

JavaScript语言基础教程 --阮一峰

  • 总结一下前面两段话的意思:要让函数定义后能被立即调用,就是要让代码被当作表达式解析,一种解决方法就是加圆括号;
  • 既然括号的作用只是让代码在解析时被解析成表达式,所以文章开头提到的两种写法是没有区别的,不过(function() {}())这种写法更多的被推荐。

不加括号可不可以?

为了避免解析的歧义,JavaScript 规定,如果function关键字出现在行首,一律解释成语句。因此,引擎看到行首是function关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。

JavaScript语言基础教程 --阮一峰

  • 针对文章开头的两种写法不加括号是不可以的,当然还有更多的方法实现函数定义是就调用,这些方式都是被允许的,使用了不同的方式让一个语句变成表示式,这也可以理解为什么叫它立即调用的函数表达式
var rn = function rn() { console.log('rn') }();

true && function(){ console.log(1) }();

0, function(){ console.log(2) }();

// 这种方式是被推荐的
!function () { console.log(3) }();

~function () { console.log(4) }();

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

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

注意:(function() {}())(function() {})()使用这两种写法时,代码所在的上一行代码结束必须有分号,或者写成这个样子;(function() {}());(function() {})()

使用场景

  • 封装特定功能的模块,起初JQuery就是使用的这种方式;
  • 还记得这个案例吗
<button class="btn">0</button>
<button class="btn">1</button>
<button class="btn">2</button>
<button class="btn">3</button>

<script>
  var btns = document.getElementsByClassName('btn')
  for(var i = 0; i < btns.length; i++) {
    btns[i].onclick = function() {
      console.log(i);
    }
  }
</script>
  • 上面这个案例中在点击任意按钮的时候打印的都是4,原因不必再做解释(使用let声明i变量也可以解决这个问题),现在咱们用立即调用的函数表达式让点击按钮打印不同的值;
// 只贴出了两种解决方式的js代码
// 第一种解决方式
var btns = document.getElementsByClassName('btn')
  for(var i = 0; i < btns.length; i++) {
    btns[i].onclick = (function(i) {
      return function() {
        console.log(i)
      }
    }(i))
  }

// 第二种解决方式
var btns = document.getElementsByClassName('btn')
for(var i = 0; i < btns.length; i++) {
  (function(i) {
    btns[i].onclick = function() {
      console.log(i)
    }
  }(i))
}

demo链接

参考文章

爱总结,爱搬砖,爱生活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值