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 相关文章推荐
extJs 文本框后面加上说明文字+下拉列表选中值后触发事件
Nov 27 Javascript
jQuery UI AutoComplete 自动完成使用小记
Aug 21 Javascript
js弹出模式对话框,并接收回传值的方法
Mar 12 Javascript
js 火狐下取本地路径实现思路
Apr 02 Javascript
JavaScript中window、doucment、body的解释
Aug 14 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
May 28 Javascript
BootStrap Validator 版本差异问题导致的submitHandler失效问题的解决方法
Dec 01 Javascript
Vue.js实战之组件的进阶
Apr 04 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
Dec 01 Javascript
React路由管理之React Router总结
May 10 Javascript
js实现列表按字母排序
Aug 11 Javascript
关于vue的列表图片选中打钩操作
Sep 09 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
php5.3 废弃函数小结
2010/05/16 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
PHP中的正则表达式实例详解
2017/04/25 PHP
win10 apache配置虚拟主机后localhost无法使用的解决方法
2018/01/27 PHP
PHP切割汉字的常用方法实例总结
2019/04/27 PHP
原创javascript小游戏实现代码
2010/08/19 Javascript
JS时间选择器 兼容IE6,7,8,9
2012/06/26 Javascript
Ext JS添加子组件的误区探讨
2013/06/28 Javascript
js Map List 遍历使用示例
2013/07/10 Javascript
javascript显示中文日期的方法
2015/06/18 Javascript
jquery实现适用于门户站的导航下拉菜单效果代码
2015/08/24 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
2015/12/13 Javascript
简单分析javascript中的函数
2016/09/10 Javascript
jquery 实时监听输入框值变化的完美方法(必看)
2017/01/26 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
2017/05/02 Javascript
JS中Attr的用法详解
2017/10/09 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
深入浅析js原型链和vue构造函数
2018/10/25 Javascript
聊聊Vue 中 title 的动态修改问题
2019/06/11 Javascript
原生JS实现汇率转换功能代码实例
2020/05/13 Javascript
vue 使用localstorage实现面包屑的操作
2020/11/16 Javascript
[03:42]2014DOTA2西雅图国际邀请赛 Navi战队巡礼
2014/07/07 DOTA
python中pass语句用法实例分析
2015/04/30 Python
深入解析Python中的urllib2模块
2015/11/13 Python
Python结合ImageMagick实现多张图片合并为一个pdf文件的方法
2018/04/24 Python
Python二叉树定义与遍历方法实例分析
2018/05/25 Python
pandas 数据归一化以及行删除例程的方法
2018/11/10 Python
英国在线购买轮胎、预订汽车、汽车维修和装配网站:Protyre
2020/04/12 全球购物
思想品德自我鉴定
2013/10/12 职场文书
经典广告词大全
2014/03/14 职场文书
教育项目合作协议书格式
2014/10/17 职场文书
九华山导游词
2015/02/03 职场文书
mysql 带多个条件的查询方式
2021/06/05 MySQL
SpringBoot 整合mongoDB并自定义连接池的示例代码
2022/02/28 MongoDB
win11怎么消除图标小盾牌?win11消除图标小盾牌解决方法
2022/08/05 数码科技