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


Posted in Javascript onNovember 18, 2015

没有区别。

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

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

foo();                   // 这是语句,Statement;解释器遇到语句是会运行它的。

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

function foo() {...}

foo();

那么为什么要 IIFE?
1.传统的方法??拢?ㄒ搴椭葱蟹挚?矗?br /> 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 对象

我在这里写过一个系列,其中一篇讲作用域和命名提升的,里面的知识点对理解 IIFE 有帮助,有兴趣的话可以继续深入阅读:https://3water.com/article/75090.htm

方式一,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用在去调用执行
方式二,调用函数,得到返回值。强制运算符使函数调用执行
(function(){})(); 是 把函数当作表达式解析,然后执行解析后的函数
相当于 var a = function(){}; a(); a得到的是函数
(function(){}()); 是把函数表达式和执行当作语句直接执行、
相当于 var a = function(){}(); a得到的是结果
最终结果是一样的、
()只是起了 自执行的作用
和 () 一样的还有很多
比如 +function (){}
这个等于 (function (){}) 一般用(function (){}) 还有个作用,就是 避免全局变量

Javascript 相关文章推荐
jQuery1.6 类型判断实现代码
Sep 01 Javascript
浅析LigerUi开发中谨慎载入common.css文件
Jul 09 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
Jan 04 Javascript
Javascript实现代码折叠功能
Aug 25 Javascript
Javascript数组循环遍历之forEach详解
Nov 07 Javascript
JavaScript评论点赞功能的实现方法
Mar 13 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
Jun 08 jQuery
初探js和简单隐藏效果的实例
Nov 23 Javascript
react的滑动图片验证码组件的示例代码
Feb 27 Javascript
javascript实现计算器功能
Mar 30 Javascript
JavaScript console的使用方法实例分析
Apr 28 Javascript
如何手动实现一个 JavaScript 模块执行器
Oct 16 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
Nov 18 #Javascript
JavaScript如何获取数组最大值和最小值
Nov 18 #Javascript
原生js模拟淘宝购物车项目实战
Nov 18 #Javascript
JavaScript统计网站访问次数的实现代码
Nov 18 #Javascript
javascript实现添加附件功能的方法
Nov 18 #Javascript
Jquery Mobile 自定义按钮图标
Nov 18 #Javascript
javascript实现对表格元素进行排序操作
Nov 18 #Javascript
You might like
php 应用程序安全防范技术研究
2009/09/25 PHP
不使用php api函数实现数组的交换排序示例
2014/04/13 PHP
php的sso单点登录实现方法
2015/01/08 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
PHP 进度条函数的简单实例
2017/09/19 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
2017/12/26 PHP
tp5实现微信小程序多图片上传到服务器功能
2018/07/16 PHP
PHP从尾到头打印链表实例讲解
2018/09/27 PHP
Laravel 不同生产环境服务器的判断实践
2019/10/15 PHP
编写兼容IE和FireFox的脚本
2009/05/18 Javascript
jquery radio 操作代码
2011/03/16 Javascript
使用滤镜设置透明导致 IE 6/7/8/9 解析异常的解决方法
2011/04/07 Javascript
引用外部js乱码问题分析及解决方案
2013/04/12 Javascript
JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】
2016/12/12 Javascript
Vue刷新修改页面中数据的方法
2018/09/16 Javascript
详解Axios 如何取消已发送的请求
2018/10/20 Javascript
vue-router源码之history类的浅析
2019/05/21 Javascript
Nodejs监控事件循环异常示例详解
2019/09/22 NodeJs
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
vue-cli单页面预渲染seo-prerender-spa-plugin操作
2020/08/10 Javascript
nuxt 每个页面head标签内容设置方式
2020/11/05 Javascript
python查询mysql,返回json的实例
2018/03/26 Python
python实现网站用户名密码自动登录功能
2019/08/09 Python
关于pytorch中网络loss传播和参数更新的理解
2019/08/20 Python
Python读写操作csv和excle文件代码实例
2020/03/16 Python
Python绘制动态水球图过程详解
2020/06/03 Python
一文解决django 2.2与mysql兼容性问题
2020/07/15 Python
使用css3制作动感导航条示例
2014/01/26 HTML / CSS
拖鞋店创业计划书
2014/01/15 职场文书
酒店行政人事部经理职务说明书
2014/02/26 职场文书
给校长的建议书
2014/03/12 职场文书
婚前财产公证书
2014/04/10 职场文书
立项申请报告范本
2015/05/15 职场文书
毛主席纪念堂观后感
2015/06/17 职场文书
Axios取消重复请求的方法实例详解
2021/06/15 Javascript
Nginx工作模式及代理配置的使用细节
2022/03/21 Servers