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 相关文章推荐
IE浏览器打印的页眉页脚设置解决方法
Dec 08 Javascript
javascript 使td内容不换行不撑开
Nov 29 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
Jan 27 Javascript
JavaScript实现防止网页被嵌入Frame框架的代码分享
Dec 29 Javascript
JavaScript 事件入门知识
Apr 13 Javascript
jQuery模拟原生态App上拉刷新下拉加载更多页面及原理
Aug 10 Javascript
JavaScript实现简单获取当前网页网址的方法
Nov 09 Javascript
jquery实现全选功能效果的实现代码
May 05 Javascript
总结几道关于Node.js的面试问题
Jan 11 Javascript
详解angularjs中如何实现控制器和指令之间交互
May 31 Javascript
在Vue-cli里应用Vuex的state和mutations方法
Sep 16 Javascript
原生JavaScript写出Tabs标签页的实例代码
Jul 20 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
浅析ThinkPHP的模板输出功能
2014/07/01 PHP
简单谈谈php中ob_flush和flush的区别
2014/11/27 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
2015/12/18 PHP
JQuery 风格的HTML文本转义
2009/07/01 Javascript
js动态添加表格数据使用insertRow和insertCell实现
2014/05/22 Javascript
javascript基于DOM实现省市级联下拉框的方法
2015/05/14 Javascript
在JavaScript中访问字符串的子串
2015/07/07 Javascript
Angular.js回顾ng-app和ng-model使用技巧
2016/04/26 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
2016/09/20 Javascript
Bootstrap源码解读模态弹出框(11)
2016/12/28 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
Javascript ES6中对象类型Sets的介绍与使用详解
2017/07/17 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
JS实现字符串去重及数组去重的方法示例
2018/04/21 Javascript
tracking.js实现前端人脸识别功能
2020/04/16 Javascript
js canvas实现五子棋小游戏
2021/01/22 Javascript
Python上传package到Pypi(代码简单)
2016/02/06 Python
解决Python找不到ssl模块问题 No module named _ssl的方法
2019/04/29 Python
python的pytest框架之命令行参数详解(上)
2019/06/27 Python
Python OpenCV之图片缩放的实现(cv2.resize)
2019/06/28 Python
Django多进程滚动日志问题解决方案
2019/12/17 Python
Python实现分数序列求和
2020/02/25 Python
自荐信的禁忌和要点
2013/10/15 职场文书
物流管理专业应届生求职信
2013/11/21 职场文书
高级护理专业毕业生推荐信
2013/12/25 职场文书
学生会主席事迹材料
2014/01/28 职场文书
八项规定整改措施
2014/02/12 职场文书
应聘教师求职信
2014/07/19 职场文书
2014年高中生自我评价范文
2014/09/26 职场文书
党员教师四风自我剖析材料
2014/09/30 职场文书
庆祝国庆节标语
2014/10/09 职场文书
给老师的感谢信
2015/01/20 职场文书
2020优秀员工演讲稿(三篇)
2019/10/17 职场文书
windows安装 redis 6.2.6最新步骤详解
2022/04/26 Redis
HTML中实现音乐或视频自动播放案例详解
2022/05/30 HTML / CSS
Mysql中mvcc各场景理解应用
2022/08/05 MySQL