你需要明白 IIFE 的原理,我简单说一下:

function foo() {...}     // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。foo();                   // 这是语句,Statement;解释器遇到语句是会运行它的。

IIFE 并非必须,传统一点可以这么写:

function foo() {...}
foo();

那么为什么要 IIFE?

  1. 传统的方法啰嗦,定义和执行分开写;
  2. 传统的方法直接污染全局命名空间(浏览器里的 global 对象,如 window

于是,开发者们想找一个可以解决以上问题的写法。那么像下面这么写行不行呢?

function foo(...){}();

当然是不能,但是为什么呢?因为 function foo(...){} 这个部分只是一个声明,对于解释器来说,就好像你写了一个字符串 "function foo(...){}",它需要使用解析函数,比如 eval() 来执行它才可以。所以把 () 直接放在声明后面是不会执行,这是错误的语法。

如何把它变得正确?说起来也简单,只要把 声明 变成 表达式(Expression) 就可以了。

实际上转变表达式的办法还是很多的,最常见的办法是把函数声明用一对 () 包裹起来,于是就变成了:

(function foo() {...})    // 这里是故意换行,实际上可以和下面的括号连起来
();

这就等价于:

var foo = function () {...};    // 这就不是定义,而是表达式了。
foo();

但是之前我们说不行的那个写法,其实也可以直接用括号包起来,这也是一种等价的表达式:

(function foo(){...}());

所以你问有没有区别?很简单:木有~

另外,刚才说过转变表达式的方式很多,的确还有很多别的写法,比如:

!function foo() {...}();

或者

+function foo() {...}();

这些都可以。

我个人挺偏爱用 void 来转变表达式,因为此关键字不会有返回值。不过这一点真的没有什么要紧的,就当我“龟毛”好了……

void function () {// 这里是真正需要的代码
}();

OK,所谓不去污染全局命名空间,是因为 IIFE 创建了一个新的函数作用域,你真正的业务代码被封装在其中,自然就不会触碰到全局对象了。如果你需要全局对象,那就 pass 给 IIFE:

void function (global) {// 在这里,global 就是全局对象了
}(this)    // 在浏览器里,this 就是 window 对象

(function ( ){...})( ) IIFE 的原理相关推荐

  1. 仿函数(functors/function objects)原理及使用

    仿函数(functors,或名 function objects,函数对象),是 STL 六大组件(Components)的重要一环,如下图: 在STL的历史上,仿函数(functors)是早期的命名 ...

  2. js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( )) 有区别?

    在SF上看到这样一个问题,我觉得问得很好,所以弄成文章收集了. 没有区别. 你需要明白 IIFE 的原理,我简单说一下: function foo() {...} // 这是定义,Declaratio ...

  3. 编译原理实验:代码生成作业(1)

    编译原理实验4:中间代码生成实验包-C++文档类资源-CSDN下载编译原理实验4:中间代码生成实验包更多下载资源.学习资料请访问CSDN下载频道.https://download.csdn.net/d ...

  4. JavaScript中的IIFE

    1. 定义 IIFE: Immediately Invoked Function Expression,意为立即调用的函数表达式,也就是说,声明函数的同时立即调用这个函数. 对比一下,这是不采用IIF ...

  5. 详解 JavaScript 的 IIFE 语法

    详解 JavaScript 的 IIFE 语法 IIFE 语法 IIFE 语法的一些变体 小括号去哪儿了? 命名的 IIFE 防止连接文件时出现问题 使用箭头函数代替函数表达式 一些不推荐的立即调用函 ...

  6. 什么是 IIFE(立即调用函数表达式)?

    它是立即调用函数表达式(Immediately-Invoked Function Expression),简称 IIFE.函数被创建后立即被执行: (function IIFE(){console.l ...

  7. JavaScript夯实基础系列(二):闭包

      在JavaScript中函数是一等公民.所谓一等公民是指函数跟其他对象一样,很普通,可以进行把函数存在数组中.作为参数传递.赋值给变量等操作.当函数作为另一个函数的返回值在外部调用时,跟该函数在函 ...

  8. 闭包应用之延迟函数setTimeout

    根据HTML 5标准,setTimeout推迟执行的时间,最少是5毫秒.如果小于这个值,会被自动增加到5ms. 每一个setTimeout在执行时,会返回一个唯一ID,把该ID保存在一个变量中,并传入 ...

  9. 详细理解JS的三座大山

    如图所示,JS的三座大山: 同步.异步 作用域.闭包 原型.原型链 1. 同步.异步 JavaScript执行机制,重点有两点: JavaScript是一门单线程语言 Event Loop(事件循环) ...

最新文章

  1. 记录一个比较完整的python项目分析架构
  2. c语言 静态链表插入排序,数据结构C语言版 表插入排序
  3. 【Flutter】Hero 动画 ( Hero 实现径向动画 | Hero 组件 createRectTween 设置 )
  4. 13_线性回归分析、线性模型、损失函数、最小二乘法之梯度下降、回归性能评估、sklearn回归评估API、线性回归正规方程,梯度下降API、梯度下降 和 正规方程对比
  5. 【最简便解法】1069 微博转发抽奖 (20分)
  6. Web前端开发笔记——第四章 JavaScript程序设计 第一节 JavaScript的基础语法
  7. 超硬核!躺进BAT以后我总结了出现最多的15道数组题
  8. python数据分析与可视化-Python数据分析与数据可视化
  9. 程超:突破瓶颈!如何不断的提高自己
  10. Xshell远程连接Linux服务器
  11. 【clickhouse】clickhouse 临时表
  12. 最全HTML与CSS基础总结,不进来看看吗?
  13. linux已使用线程,在Linux中使用线程
  14. 关于Dos窗口的设置
  15. python 英语翻译 excel_Excel自动翻译
  16. 第3章 形式语言与自动机
  17. java调用 火眼臻睛,火眼臻睛车牌识别SDK评测
  18. java同期_Java日期处理-本期,同期,上期
  19. 【AAAI 2021】全部接受论文列表(一)
  20. 云计算发展趋势都有哪些 如何快速入行云计算

热门文章

  1. PyTorch常用代码段整理合集
  2. 大小端、位段和内存对齐
  3. Nginx+Tomcat+Memcached实现tomcat集群和session共享
  4. 求解决方法_解决方法
  5. 如何看待雅虎套现760亿美元从阿里巴巴退出?
  6. 熊猫直播宣布停服:主站流浪计划第一阶段开启
  7. CSS3选择非第一个子元素
  8. android icon命名规则,安卓手机的APP图标尺寸规范和图标命名规范
  9. java中怎么使用json数据_JAVA中使用JSON进行数据传递
  10. vscode 调试_如何使用VSCode调试JS?