JavaScript立即执行函数(IIFE)详解与实战应用

作者:木棉时间:2026-10-24 19:00:59浏览:82

本文深入解析JavaScript中的立即执行函数(IIFE),涵盖其标准写法、多种表达式实现方式(如逻辑运算符、new关键字等)以及带参数的用法。通过经典面试题案例,展示如何利用IIFE结合闭包解决循环中的变量捕获问题,帮助开发者掌握创建独立作用域的技巧。

在JavaScript开发中,你可能会遇到一些特殊的函数定义方式,例如以下示例所示:

立即执行函数的基本格式

这类函数在浏览器加载页面时会自动执行,无需手动调用。此前在讲解闭包时也曾提及此类函数,通常被称为立即执行函数(Immediately Invoked Function Expression,简称IIFE)。

立即执行函数具备以下显著特征:

  • 自动触发执行
  • 仅执行一次

立即执行函数的基本格式

立即执行函数通常遵循以下标准格式:


# 格式一(//W3C 推荐这种写法)
(function (){
 }())
 
#格式二 (但是这个才是最常用的方式之一)
(function (){
 })();
 

从上述格式可以看出,立即执行函数通常不定义函数名。因为函数无需通过名称进行后续调用,这与使用字面量方式定义函数的作用类似,省略函数名更为简洁。

接下来,结合闭包概念与立即执行函数,通过一个具体示例进行说明:


var fun=(
function(){
  function test(a,b){
      console.log(a+b);
  }    
  return test;
}
)()
 

立即执行函数的基本格式

立即执行函数的其他实现方式——表达式

虽然前文介绍了标准的立即执行函数格式,但还存在其他实现该功能的方法。例如以下代码并非采用标准格式:


!function(){
    console.log("test");
}()

立即执行函数的基本格式

观察输出结果,第一行输出“test”,体现了立即执行函数的执行效果;第二行输出true,是因为前面添加了感叹号(!)。在之前的隐式转换讲解中提到,感叹号后的表达式会被强制转换为布尔类型。

这里产生了一个疑问:为什么这种方式能够实现立即执行的效果?

为了分析这种情况,我们先看一个普通的表达式函数:


var test=function(){
    console.log("test表达式")
}
#这样声明后,如何使用呢?如下
test();
 

立即执行函数的基本格式

此时可以产生一个大胆的设想:如果给变量赋值的函数,通过“变量名+()”的方式即可执行,那么是否可以直接编写这样的结构?


var test=function(){
    console.log("test表达式")
}()

立即执行函数的基本格式

由此可见,表达式函数也具备立即执行的效果。

(补充说明:之所以输出undefined,是因为该函数本身没有return语句,因此浏览器控制台会输出undefined。)

那么,是否可以直接在函数定义后紧跟括号来执行呢?


function(){
    console.log("test表达式")
}()

立即执行函数的基本格式

结果显示,必须基于表达式的前提,才能在函数后添加括号(),否则会导致报错。

由此引发另一个大胆的想法:既然感叹号(!)能将函数转换为表达式函数,从而允许后续添加()直接运行,那么如果在函数前添加加号(+)会怎样?


+function(){
    console.log("test表达式")
}()
 

立即执行函数的基本格式

既然加号可行,那么:

+ -
! ~

当然,乘号和除号无法实现此效果。此外,还有一个神奇的关键字也能产生类似效果,那就是new和void。


new function(){
    console.log("test表达式")
}()

立即执行函数的基本格式

另外,逻辑运算符||和&&也能实现这一功能。

不过,这需要根据其特性在前方添加真值或假值才能生效,单独使用是不行的。


1 && function(){
    console.log("test表达式")
}()
 或者
0 || function(){
    console.log("test表达式")
}()
 

立即执行函数的基本格式

还有一个神奇的符号(逗号)也能实现此功能:


1,function(){
    console.log("test表达式")
}()
 

立即执行函数的基本格式

可以看出,如果使用逗号,无论前面的表达式真假,都会执行后面的表达式函数。

立即执行函数支持参数传递

立即执行函数同样可以接收参数,具体示例如下:


(function(a,b){
    console.log(a,b)
})(1,2)
 

立即执行函数的基本格式

应用场景

这是一个非常经典的面试题。首先创建一个HTML文件:


<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
<title>test</title> 
</head>
<body>
<ul id=”test”>
    <li>这是第一条</li>
     <li>这是第二条</li>
    <li>这是第三条</li>
 </ul>
<script>
  var liList=document.getElementsByTagName('li');
     for(var i=0;i<liList.length;i++)
     {
         liList[i].onclick=function(){
             console.log(i);
         }
     };
</script>
 </body>
</html>

目标是点击第几个li标签就输出对应的数字,但实际结果往往不符合预期。

立即执行函数的基本格式

这是因为在点击li元素时,for循环早已执行完毕。此前学习的let关键字也可以解决这个问题。


  var liList=document.getElementsByTagName('li');
     for(let i=0;i<liList.length;i++)
     {
         liList[i].οnclick=function(){
             console.log(i);
         }
     };

立即执行函数的基本格式

虽然let可以解决该问题,但并未使用立即执行函数。当然,也可以通过立即执行函数来进行修改。


 var liList=document.getElementsByTagName('li');
     for(let i=0;i<liList.length;i++)
     {  (function(a){
        liList[a].οnclick=function(){
             console.log(a);
         } 
      })(i)
      };

立即执行函数的基本格式

可以看出,立即执行函数会形成自己的封闭空间,不受外部其他变量的影响。如果在此基础上添加return语句,就是一个标准的闭包结构。

总结

本文到此结束,希望能对你有所帮助。欢迎继续关注本站获取更多精彩内容!

作者最新文章