原文出处:http://www.dnew.cn/post/196.htm
先看下下面几种写法
1.functionf(x){returnx*x;};f(x);
2.(function(x){returnx*x;})(x);
3.(function(x){returnx*x;}(x));
第一种我们应该都很熟悉了,这是我们经常使用的写法。第二第三种都是匿名函数的写法。
--------------------------------------------------------------------------------
第二种
可以这样理解:
varf=function(x){returnx*x;};f()
那我们不通过f这个变量来引用函数就是
function(){}()
然而这样肯定是错误的就像
varf=1+2;
f=f*0;
与
varf=1+2*0;
结果不同一样。
要得到正确结果只能:
f=(1+2)*0;
也就是要明确的标识出程序块,即:
(function(){})()
肯你有疑问:括号“()”到底是不是起到了标识代码块的作用?
我们可以用JavaScript的内置函数检测一下!
举一个最简单的例子:
alert(4)
这段代码会弹出提示内容是“4”
改成这样
(alert)(4)
可以看到执行的效果和上一段代码一样。
这种形式的函数执行也被很多JavaScript框架所采用。
--------------------------------------------------------------------------------
第三种,如果你用过jsvm框架的话就会发现里面的代码使用了这种形式。
那如何解释第三种情况呢?
为了弄明白浏览器是如何理解这样的写法的,我们可以利用一下MozillaFirefox的错误控制台功能。
在代码中插入一段错误代码,代码段如下:
(function(s){s+s}(1)).splice();
打开MozillaFirefox的错误控制台,可以看到有如下的错误提示
错误:(function(s){})(1)hasnoproperties
源文件:file:///C:/Documents…….html
行:18
可以认为,浏览器对于
(function(s){s+s}(1))
这样的代码按照
(function(s){s+s})(1)
来解析的。
--------------------------------------------------------------------------------
到此可能你有这样的认识:
functionf(x){returnx*x;};f(x);==(function(x){returnx*x;})(x);==(function(x){returnx*x;}(x));
但是他们还是有区别的,
首先,对于像第二和第三种形式,其它的函数和代码是不可能调用所定义的函数的,有一种说发把这样的函数称为匿名函数或者函数直接量。
其次,第二和第三种形式执行的函数,中间变量不会污染到全局命名空间,你可以把中间的代码看作纯粹的子过程调用。
当然使用后面两种形式的函数定义可以很容易的实现闭包。
看一个例子:
/*
http://jibbering.com/faq/faq_notes/closures.html(Dnew.CN注)
Aglobalvariable-getImgInPositionedDivHtml-isdeclaredand
assignedthevalueofaninnerfunctionexpressionreturnedfrom
aone-timecalltoanouterfunctionexpression.
ThatinnerfunctionreturnsastringofHTMLthatrepresentsan
absolutelypositionedDIVwrappedroundanIMGelement,suchthat
allofthevariableattributevaluesareprovidedasparameters
tothefunctioncall:-
*/
vargetImgInPositionedDivHtml=(function(){
/*The-buffAr-Arrayisassignedtoalocalvariableofthe
outerfunctionexpression.Itisonlycreatedonceandthatone
instanceofthearrayisavailabletotheinnerfunctionsothat
itcanbeusedoneachexecutionofthatinnerfunction.
Emptystringsareusedasplaceholdersforthedatethatisto
beinsertedintotheArraybytheinnerfunction:-
*/
varbuffAr=[
'<divid="',
'',//index1,DIVIDattribute
'"style="position:absolute;top:',
'',//index3,DIVtopposition
'px;left:',
'',//index5,DIVleftposition
'px;width:',
'',//index7,DIVwidth
'px;height:',
'',//index9,DIVheight
'px;overflow:hidden;"><imgsrc="',
'',//index11,IMGURL
'"width="',
'',//index13,IMGwidth
'"height="',
'',//index15,IMGheight
'"alt="',
'',//index17,IMGalttext
'"></div>'
];
/*Returntheinnerfunctionobjectthatistheresultofthe
evaluationofafunctionexpression.Itisthisinnerfunction
objectthatwillbeexecutedoneachcallto-
getImgInPositionedDivHtml(...)-:-
*/
return(function(url,id,width,height,top,left,altText){
/*Assignthevariousparameterstothecorresponding
locationsinthebufferarray:-
*/
buffAr[1]=id;
buffAr[3]=top;
buffAr[5]=left;
buffAr[13]=(buffAr[7]=width);
buffAr[15]=(buffAr[9]=height);
buffAr[11]=url;
buffAr[17]=altText;
/*Returnthestringcreatedbyjoiningeachelementinthe
arrayusinganemptystring(whichisthesameasjust
joiningtheelementstogether):-
*/
returnbuffAr.join('');
});//:Endofinnerfunctionexpression.
})();
/*^^-:Theinlineexecutionoftheouterfunctionexpression.*/