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 相关文章推荐
CSS JavaScript 实现菜单功能 改进版
Dec 09 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
Mar 23 Javascript
基于jQuery实现点击弹出层实例代码
Jan 01 Javascript
bootstrap实现弹窗和拖动效果
Jan 03 Javascript
关于vuex的学习实践笔记
Apr 05 Javascript
jQuery之动画ajax事件(实例讲解)
Jul 18 jQuery
使用jQuery实现鼠标点击左右按钮滑动切换
Aug 04 jQuery
Angular2 组件间通过@Input @Output通讯示例
Aug 24 Javascript
基于ajax和jsonp的原生封装(实例)
Oct 16 Javascript
详解vue中组件参数
Jul 09 Javascript
详解小程序如何避免多次点击,重复触发事件
Apr 08 Javascript
Vue element-ui父组件控制子组件的表单校验操作
Jul 17 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计算税后工资的方法
2015/07/28 PHP
PHP水印类,支持添加图片、文字、填充颜色区域的实现
2017/02/04 PHP
PHP生成(支持多模板)二维码海报代码
2018/04/30 PHP
JS input文本框禁用右键和复制粘贴功能的代码
2010/04/15 Javascript
JavaScript的类型简单说明
2010/09/03 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
jQuery点击tr实现checkbox选中的方法
2013/03/19 Javascript
让js弹出窗口居前显示的实现方法
2013/07/10 Javascript
JS Replace 全部替换字符的用法小结
2013/12/24 Javascript
javascript读取Xml文件做一个二级联动菜单示例
2014/03/17 Javascript
javascript制作的滑动图片菜单
2015/05/15 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
jQuery基于ajax实现星星评论代码
2015/08/07 Javascript
Jquery实现$.fn.extend和$.extend函数
2016/04/14 Javascript
利用Angularjs和Bootstrap前端开发案例实战
2016/08/27 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
element el-input directive数字进行控制
2018/10/11 Javascript
vue使用better-scroll实现滑动以及左右联动
2020/06/30 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
JavaScript中layim之整合右键菜单的示例代码
2021/02/06 Javascript
python调用短信猫控件实现发短信功能实例
2014/07/04 Python
Python实现从URL地址提取文件名的方法
2015/05/15 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
python计算两个地址之间的距离方法
2018/06/09 Python
Python学习笔记之函数的参数和返回值的使用
2019/11/20 Python
Html5页面上如何禁止手机虚拟键盘弹出
2020/03/19 HTML / CSS
阿拉伯时尚购物网站:Nisnass
2021/02/07 全球购物
JBL加拿大官方商店:扬声器、耳机等
2020/10/23 全球购物
同学聚会欢迎辞
2014/01/14 职场文书
试用期员工考核制度
2014/01/22 职场文书
金融管理毕业生求职信
2014/03/03 职场文书
售后服务承诺书模板
2014/05/21 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
英文产品推荐信
2015/03/27 职场文书
商标侵权律师函
2015/05/27 职场文书
pandas进行数据输入和输出的方法详解
2022/03/23 Python