A-A+

立即执行函数: (function ( ){…})( ) 与 (function ( ){…}( )) 有什么区别?

2016年01月11日 JavaScript 暂无评论 阅读 55 次

没有区别。

你需要明白 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://blog.segmentfault.com/nightire/1190000000348228

原文地址:http://segmentfault.com/q/1010000000442042

列子demo:hdwjw.bjhd.gov.cn/js/init.js

// JavaScript Document
(function (e) {

if (!e) {
return;
}

e.DOM = {};

DOM.init = function () { //初始化方法

}

//选项卡
DOM.tab = function(fn, obj, tabObj){
if($(obj).eq(0).text()=="网上人口学校"){
$(obj).eq(6).addClass('selected');
$(tabObj).eq(6).show();
$(obj).bind(fn,function(){
$(this).addClass('selected').siblings().removeClass('selected');
$(tabObj).eq($(this).index()).show().siblings().hide();
})
}else{
$(obj).eq(0).addClass('selected');
$(tabObj).eq(0).show();
$(obj).bind(fn,function(){
$(this).addClass('selected').siblings().removeClass('selected');
$(tabObj).eq($(this).index()).show().siblings().hide();
})
}

}

调用发放:

$(function(){
$('.box2-tabs-nav li:last-child').css('border-right','none');
DOM.tab('mouseover','#tab01Nav li','#tab01Con ul');
DOM.tab('mouseover','.box2-tabs-ul01 li','.box2-tabs-content');
DOM.tab('click','#tab03Nav li','#tab03Con ul');
DOM.tab('mouseover','#tab06Nav li','#tab06Con div');
DOM.tab('mouseover','#navTab li','#navCon div');
DOM.tab('click','#tab07Nav li','.tab07_list');
DOM.indexImgScroll();
DOM.indextab05ConScroll();
$('#ewm01').css({'top':$('#wsjswb').offset().top-134,'left':$('#wsjswb').offset().left-25});
$('#ewm02').css({'top':$('#wsjswb').offset().top-134,'left':$('#wsjswb').offset().left+75});
$('#wsjswb').mouseover(function(){
$('#ewm01,#ewm02').show();
}).mouseout(function(){
$('#ewm01,#ewm02').hide();
});
$('#ewm03').css({'top':$('#haidianwx').offset().top-120,'left':$('#haidianwx').offset().left+26});
$('#haidianwx').mouseover(function(){
$('#ewm03').show();
}).mouseout(function(){
$('#ewm03').hide();
});
});

标签:

给我留言

Copyright © web前端技术开发个人博客 保留所有权利  京ICP备14060653号 Theme  Ality

用户登录