js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
作者:bea
没有区别。 你需要明白 IIFE 的原理,我简单说一下: 代码如下: function foo() {...} // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。 foo(); // 这是语句,Statement;解释器遇到语句是会运行它的。 IIFE 并非必须,传统一点可以这么写: 代码如下: function foo() {...} foo(); 那么为什么要 IIFE? 1.传统的方法啰嗦,定义和执行分开写; 2.
没有区别。
你需要明白 IIFE 的原理,我简单说一下:
代码如下:
function foo() {...} // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。
foo(); // 这是语句,Statement;解释器遇到语句是会运行它的。
IIFE 并非必须,传统一点可以这么写:
代码如下:
function foo() {...}
foo();
那么为什么要 IIFE? 1.传统的方法啰嗦,定义和执行分开写; 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 有帮助,有兴趣的话可以继续深入阅读:http:///article/75090.htm
方式一,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用在去调用执行 方式二,调用函数,得到返回值。强制运算符使函数调用执行 (function(){})(); 是 把函数当作表达式解析,然后执行解析后的函数 相当于 var a = function(){}; a(); a得到的是函数 (function(){}()); 是把函数表达式和执行当作语句直接执行、 相当于 var a = function(){}(); a得到的是结果 最终结果是一样的、 ()只是起了 自执行的作用 和 () 一样的还有很多 比如 +function (){} 这个等于 (function (){}) 一般用(function (){}) 还有个作用,就是 避免全局变量
有用 | 无用
你需要明白 IIFE 的原理,我简单说一下:
代码如下:
function foo() {...} // 这是定义,Declaration;定义只是让解释器知道其存在,但是不会运行。
foo(); // 这是语句,Statement;解释器遇到语句是会运行它的。
IIFE 并非必须,传统一点可以这么写:
代码如下:
function foo() {...}
foo();
那么为什么要 IIFE? 1.传统的方法啰嗦,定义和执行分开写; 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 有帮助,有兴趣的话可以继续深入阅读:http:///article/75090.htm
方式一,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用在去调用执行 方式二,调用函数,得到返回值。强制运算符使函数调用执行 (function(){})(); 是 把函数当作表达式解析,然后执行解析后的函数 相当于 var a = function(){}; a(); a得到的是函数 (function(){}()); 是把函数表达式和执行当作语句直接执行、 相当于 var a = function(){}(); a得到的是结果 最终结果是一样的、 ()只是起了 自执行的作用 和 () 一样的还有很多 比如 +function (){} 这个等于 (function (){}) 一般用(function (){}) 还有个作用,就是 避免全局变量
有用 | 无用
猜你喜欢
您可能感兴趣的文章:
- Node.js中使用socket创建私聊和公聊聊天室
- Jquery实现仿京东商城省市联动菜单
- javascript实现二级级联菜单的简单制作
- jquery通过扩展select控件实现支持enter或focus选择的方法
- javascript中checkbox使用方法实例演示
- jquery实现表格隔行换色效果
- javascript设计简单的秒表计时器
- 跟我学习javascript的定时器
- 分享纯手写漂亮的表单验证
- javascript获取系统当前时间的方法
- jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构
- javascript电商网站抢购倒计时效果实现
- 跟我学习javascript的Date对象
- 跟我学习javascript的this关键字
- jQuery 1.9.1源码分析系列(十)事件系统之绑定事件
- 基于Jquery代码实现手风琴菜单
- 跟我学习javascript的作用域与作用域链
- 每天一篇javascript学习小结(属性定义方法)
- 理解 JavaScript Scoping & Hoisting(二)