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 相关文章推荐
Jquery右下角抖动、浮动 实例代码(兼容ie6、FF)
Aug 15 Javascript
JavaScript实现的in_array函数
Aug 27 Javascript
基于javascript实现右下角浮动广告效果
Jan 08 Javascript
再谈javascript常见错误及解决方法
Sep 16 Javascript
基于Phantomjs生成PDF的实现方法
Nov 07 Javascript
View.post() 不靠谱的地方你知道多少
Aug 29 Javascript
详解angular笔记路由之angular-router
Sep 12 Javascript
微信小程序之多列表的显示和隐藏功能【附源码】
Aug 06 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
Nov 17 Javascript
vue3.0中使用postcss-pxtorem的具体方法
Nov 20 Javascript
Vuejs通过拖动改变元素宽度实现自适应
Sep 02 Javascript
echarts实现晶体球面投影的实例教程
Oct 10 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/14 PHP
php-msf源码详解
2017/12/25 PHP
屏蔽F1~F12的快捷键的js函数
2010/05/06 Javascript
jQuery效果 slideToggle() 方法(在隐藏和显示之间切换)
2011/06/28 Javascript
iframe窗口高度自适应的实现方法
2014/01/08 Javascript
jquery动态添加元素事件失效问题解决方法
2014/05/23 Javascript
JSON.parse()和JSON.stringify()使用介绍
2014/06/20 Javascript
超赞的jQuery图片滑块动画特效代码汇总
2016/01/25 Javascript
jQuery的内容过滤选择器学习教程
2016/04/18 Javascript
JavaScript的instanceof运算符学习教程
2016/06/08 Javascript
js捕捉键盘事件和按键键值的方法
2016/10/10 Javascript
jquery Banner轮播选项卡
2016/12/26 Javascript
Javascript 实现计算器时间功能详解及实例(二)
2017/01/08 Javascript
jQuery.cookie.js使用方法及相关参数解释
2017/03/06 Javascript
微信小程序联网请求的轮播图
2017/07/07 Javascript
JavaScript数组的5种迭代方法
2017/09/29 Javascript
对Vue beforeRouteEnter 的next执行时机详解
2018/08/25 Javascript
layui下拉框获取下拉值(select)的例子
2019/09/10 Javascript
javascript Canvas动态粒子连线
2020/01/01 Javascript
解决父组件将子组件作为弹窗调用只执行一次created的问题
2020/07/24 Javascript
如何构建一个Vue插件并生成npm包
2020/10/26 Javascript
[02:37]2018DOTA2亚洲邀请赛赛前采访-EG篇
2018/04/03 DOTA
Python实现抓取网页并且解析的实例
2014/09/20 Python
python爬虫自动创建文件夹的功能
2018/08/01 Python
Python判断telnet通不通的实例
2019/01/26 Python
基于多进程中APScheduler重复运行的解决方法
2019/07/22 Python
Python 日志logging模块用法简单示例
2019/10/18 Python
pycharm显示远程图片的实现
2019/11/04 Python
pyinstaller打包找不到文件的问题解决
2020/04/15 Python
美国领先的男士和女士内衣购物网站:Freshpair
2019/02/25 全球购物
Footshop乌克兰:运动鞋的最大选择
2019/12/01 全球购物
大学生毕业求职自荐书范文
2014/02/04 职场文书
工作岗位说明书模板
2014/05/09 职场文书
购房个人委托书范本
2014/10/11 职场文书
初中家长评语和期望
2014/12/26 职场文书
2015年初中教师个人工作总结
2015/07/21 职场文书