介绍

IIFE(Immediately Invoked Function Expression),中文名称:立即执行函数表达式,其实IIFE最早并不叫这个名字,而是叫做Self-Executing Anonymous Function,即自执行匿名函数。根据MDN的资料,IIFE这个说法最早由Ben Alman于2010年提出,下面我们一起来看看这个名字的来龙去脉。

2010年11月5日,Ben Alman写下来他的著名文章:Immediately-Invoked Function Expression (IIFE),标志着IIFE这个名字的诞生。

在文章中,Ben Alman称他是一个对待术语非常严谨的人,之前他多次看到Self-Executing Anonymous Function这个说法,觉得不是很恰当,于是他提出了Immediately-Invoked Function Expression这个说法。

IIFE到底是咋来的?

当我们定义一个函数或者一个函数表达式时,你得到的是一个名字,通过这个名字,你就可以调用这个函数。

下面这两段代码,第一个定义了一个普通函数,第二个定义了一个函数表达式,这两种形式,我们都可以通过标识符foo来调用它们。

// 普通函数
function foo() {
console.log('I am a function');
} // 函数表达式
const foo = function() {
console.log('I am a function expression');
};

也就是说,当javascript解释器遇到全局function关键字,或者一个函数内部的function关键字时,会将其解释为一个函数声明。

然而函数声明是无法直接调用的,所以下面的写法会导致错误:

function foo() {
console.log('I am a function'); // Uncaught SyntaxError: Unexpected token ')'
}();

我们来分析一下,上面这段代码,javascript解释器会将其解释为一个函数声明,和一个分组操作符(()), 分组操作符是用来改变运算符优先级的,里面必须有表达式才行,所以javascript解释器会报错。

那我们就给它一个表达式:

function foo() {
console.log('I am a function'); // Uncaught SyntaxError: Unexpected token ')'
}(1);

这回代码不报错了,但是这段代码毫无意义,这个函数并没有执行,实际上这段代码与下面的代码等价:

function foo() {
console.log('I am a function');
} (1);

它的返回值就是1,这不是我们想要的结果,我们需要函数定义后能立即被执行,那就需要我们告诉javascript解释器,这个函数是一个表达式,而不是一个声明,因为表达式可以立即执行,但是声明不能。

而在javascript中,生成表达式最简单的方式就是用()包裹起来,于是有了下面的代码

(function foo() {
console.log('I am a function');
});

这样函数声明就变成了一个函数表达式,但是这个表达式没有名字,我们没法调用它,我们先给它一个名字,然后通过名字调用它。

const bar = (function foo() {
console.log('I am a function');
}); bar(); // I am a function

这样完全没有问题,但是这里的bar实在有点多余,实际上bar

(function foo() {
console.log('I am a function');
});

是等价的,既然bar()可以调用函数,那么我们直接在函数表达式末尾加上(),也可以调用这个函数,于是就有了下面的代码,这就是IIFE的由来。

(function foo() {
console.log('I am a function');
})();

()写在外层的括号内也一样,这种方式颇得javascript专家Douglas Crockford的青睐。我本人更喜欢第一种。

(function() {
console.log('I am a function');
}());

IIFE的变种

由上面介绍可知,生成IIFE的精髓就是将函数声明变成函数表达式,而在javascript中,生成表达式可不止使用()包裹起来这一种方式,还有很多其他的方式可以实现。于是IIFE也就是产生了诸多变种。

这个变种利用赋值运算符=来实现,赋值运算符是将右侧表达式的值赋值给左侧变量的,所以它右侧的部分被解析成了函数表达式及其调用。

const i = function() {
console.log('I am an IIFE');
}();

下面的表中使用逻辑运算符来生成表达式。

true & (function() {
console.log('I am an IIFE');
}());

还有下面这些,都是利用一元运算符来生成函数表达式。

!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

最后来一个不为人知的,void运算符会对其右侧的表达是求值然后返回undefined。(void expression - 先对expression求值,然后返回undefined)。

void function() {
console.log('I am an IIFE');
}();

还有使用new运算符来生成IIFE,这种方式比较少见,因为它会创建一个新的对象。

new function() {
console.log('I am an IIFE');
}();

这些方式都比较偏门了,不建议使用,只是用来帮助我们理解IIFE的。

为什么Self-Executing Anonymous Function这个名字不好?

Ben Alman认为这个名字有两个问题:

Self-Executing:这个名字暗示函数会调用自己,但是实际上函数是立即被执行的,而不是调用它自身。

比如下面的几段代码都会调用自己,但是这并不是IIFE的语义。

// 递归调用自身
function foo() { foo(); // 使用arguments.callee调用自身
const foo = function() { arguments.callee(); };

Anonymous:这个名字暗示函数是匿名的,但实际上函数可以有名字,也可以没有名字,比如下面的例子:

// 有名字的IIFE
(function foo() {
console.log('I am an IIFE');
})();

参考

https://web.archive.org/web/20171201033208/http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife

大家有时间可以去拜读Ben Alman的原文,大佬写的东西就是不一样,通俗易懂,是我辈楷模!

javascript中IIFE(立即执行函数表达式)到底是咋来的?的更多相关文章

  1. [转]Javascript中的自执行函数表达式

    [转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...

  2. 深入理解javascript中的立即执行函数(function(){…})()

    投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...

  3. javascript中的立即执行函数(function(){…})()

    javascript中的立即执行函数(function(){…})() 深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包 ...

  4. 深入理解javascript中的立即执行函数

    这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是用(function(){…})()包住业务代码,使用jquery时比较常见,需要的朋友可以 ...

  5. 【JavaScript专题】--- 立即执行函数表达式

    一 什么是立即执行函数表达式 立即执行函数表达式,其实也可以叫初始化函数表达式,英文名:IIFE,immediately-inovked-function expression.立即执行函数表达式就是 ...

  6. 【转】深入理解javascript中的立即执行函数(function(){…})()

    javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解. ( f ...

  7. javascript中的自执行函数

    学习es6的时候遇到了自执行函数,感觉有必要写下来,一方面加深自己的记忆,另一方面还能分享给大家. 什么是自执行函数? 自执行函数就是为了不污染全局变量命名空间的一中匿名函数,相当于自己创建了一个作用 ...

  8. 理解javascript中的立即执行函数(function(){})()

    之前看了好多代码,都有用到这种函数的写法,但是都没认真的去想为什么会这样写,今天开始想学习下jquery的源码,发现jquery也是使用这种方式,用(function(window, undefine ...

  9. javascript中的立即执行函数的原理

    形如 ((function Test(a) { //code here... })('Hello')); 被称作立即执行函数. 首先需要了解的是,这并不是一种hack,这是javascript的基本语 ...

  10. IIFE 立即执行函数表达式-模块化

    1)立即执行 2)表达式 3)括号,分号结束 | 前缀运算符 | 表达式上下文 4)只需要执行一次,内部变量无需维护,可用于初始化 (function( ) { })( ); 或 (function( ...

随机推荐

  1. Log4j2 重大漏洞,编译好的log4j-2.15.0.jar包下载

    背景 12 月 10 日凌晨,Apache 开源项目 Log4j 的远程代码执行漏洞细节被公开,由于 Log4j 的广泛使用,该漏洞一旦被攻击者利用会造成严重危害.受本次漏洞影响的版本范围为Apach ...

  2. devops 2024

    What is DevOps? DevOps is a mindset, a culture, and a set of technical practices. It provides commun ...

  3. Python合成多个视频为一个脚本

    编写背景: 由于线上用户反馈媒体添加页加载时间很长,猜测是由于本地视频内存过大引起,于是编写此脚本以便快速生成内存很大的视频 代码如下: # coding=utf-8 from moviepy.edi ...

  4. windows 环境下vs code配置go mod 包管理进行开发,终于解决go mod 模式下可以编译运行,但引入包"github.com/gin-gonic/gin"的飘红黄波浪警告

    最近在积极的转入go后端开发,学习gin的时候,能够编译运行,但是在improt github.com/gin-gonic/gin 波浪警告 当时忘记截图了,类似于这样的波浪警告 , 内容大概是&qu ...

  5. 关于wireshark抓包工具抓取登录数据的一点心得

    研究这个软件很久了,一直处于门外汉状态,今天终于用它抓到点有用的东西,做个简单的笔记吧,后面再继续完善. 最近研究跨域自动登录时一直不太顺利,今天就仿照网上前辈们的方法,用wireshark先抓一下手 ...

  6. Email邮箱验证码发送

    以下文件保存到/static/email.txt <!DOCTYPE html> <html lang="en" xmlns:th="http://ww ...

  7. MongoDB学习(二)

    MongoDB基本操作 查看数据库 语法: show databases 选择数据库 语法:use 数据库名 注意:在MongoDB中选择不存在的数据库不会报错,后期当该数据库有数据时,系统会自动创建 ...

  8. [开源] .Net 使用 ORM 访问 人大金仓数据库

    前言 京人大金仓信息技术股份有限公司(以下简称"人大金仓")是具有自主知识产权的国产数据管理软件与服务提供商.人大金仓由中国人民大学一批最早在国内开展数据库教学.科研.开发的专家于 ...

  9. c#运算符重载(operator)

    适用范围:C# 7.0及以上版本 C#学习-运算符重载(operator) - 百度文库 (baidu.com) 官网文档:Operator overloading - C# reference | ...

  10. 最强AI数字人,口型、表情、动作全同步!Kairos下载介绍

    在数字化浪潮汹涌澎湃的今天,视频合成技术如同一颗璀璨的明星,照亮了内容创作的广阔天地 Kairos是一款顶级数字人制作工具,它基于先进的 AI 算法,能够快速克隆出用户的数字分身,并且精准匹配外貌.声 ...