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 相关文章推荐
JS实多级联动下拉菜单类,简单实现省市区联动菜单!
May 03 Javascript
JavaScript获得指定对象大小的方法
Jul 01 Javascript
vue自定义指令实现v-tap插件
Nov 03 Javascript
jQuey将序列化对象在前台显示地实现代码(方法总结)
Dec 13 Javascript
老生常谈jacascript DOM节点获取
Apr 17 Javascript
bootstrap响应式导航条模板使用详解(含下拉菜单,弹出框)
Nov 17 Javascript
JS实现为动态创建的元素添加事件操作示例
Mar 17 Javascript
VUE引入第三方js包及调用方法讲解
Mar 01 Javascript
使用uni-app开发微信小程序的实现
Dec 13 Javascript
Vue中qs插件的使用详解
Feb 07 Javascript
在Echarts图中给坐标轴加一个标识线markLine
Jul 20 Javascript
Angular短信模板校验代码
Sep 23 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快速统计某个数据库中每张表的数据量
2012/09/04 PHP
Laravel 中获取上一篇和下一篇数据
2015/07/27 PHP
PHP Yii框架之表单验证规则大全
2015/11/16 PHP
WordPress中给文章添加自定义字段及后台编辑功能区域
2015/12/19 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
多广告投放代码 推荐
2006/11/13 Javascript
jquery $.getJSON()跨域请求
2011/12/21 Javascript
jQuery创建平滑的页面滚动(顶部或底部)
2013/02/26 Javascript
JavaScript获取onclick、onchange等事件值的代码
2013/07/22 Javascript
JS图片切换的具体方法(带缩略图版)
2013/11/12 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
JavaScript学习笔记之数组求和方法
2016/03/23 Javascript
DropDownList实现可输入可选择(两种版本可选)
2016/12/07 Javascript
微信小程序 标签传入数据
2017/05/08 Javascript
对vux点击事件的优化详解
2018/08/28 Javascript
vue-router判断页面未登录自动跳转到登录页的方法示例
2018/11/04 Javascript
Node.js如何优雅的封装一个实用函数的npm包的方法
2019/04/29 Javascript
JavaScript剩余操作符Rest Operator详解
2019/07/20 Javascript
vue悬浮可拖拽悬浮按钮的实例代码
2019/08/20 Javascript
VUE中使用HTTP库Axios方法详解
2020/02/05 Javascript
微信小程序scroll-view点击项自动居中效果的实现
2020/03/25 Javascript
Python使用py2neo操作图数据库neo4j的方法详解
2020/01/13 Python
使用django自带的user做外键的方法
2020/11/30 Python
python 利用jieba.analyse进行 关键词提取
2020/12/17 Python
HTML5 File API改善网页上传功能
2009/08/19 HTML / CSS
HTML5实现一个能够移动的小坦克示例代码
2013/09/02 HTML / CSS
用HTML5制作一个简单的弹力球游戏
2015/05/12 HTML / CSS
七年级音乐教学反思
2014/01/26 职场文书
基层干部个人对照检查及整改措施
2014/10/28 职场文书
神农溪导游词
2015/02/11 职场文书
团队拓展训练心得体会
2016/01/12 职场文书
自荐信大全
2019/03/21 职场文书
你为什么是穷人?可能是这5个缺点造成
2019/07/11 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
分享7个 Python 实战项目练习
2022/03/03 Python
Spring Boot 的创建和运行示例代码详解
2022/07/23 Java/Android