先看下下面幾種寫法
2.(function(x){return x*x;})(x);
3.(function(x){return x*x;}(x));
第一種我們應該都很熟悉了,這是我們經常使用的寫法。第二第三種都是匿名函數的寫法。
第二種
可以這樣理解:
- var f=function(x) {return x*x;};f()
那我們不通過f這個變量來引用函數就是
- function(){}()
然而這樣肯定是錯誤的就像
- var f=1+2;
- f=f*0;
與
- var f=1+2*0;
結果不同一樣。
要得到正確結果只能:
- f=(1+2)*0;
也就是要明確的標識出程序塊,即:
- (function(){})()
肯你有疑問:括號“()”到底是不是起到了標識代碼塊的作用?
我們可以用JavaScript的內置函數檢測一下!
舉一個最簡單的例子:
- alert(4)
這段代碼會彈出提示內容是“4”
改成這樣
- (alert)(4)
可以看到執行的效果和上一段代碼一樣。
這種形式的函數執行也被很多JavaScript框架所採用。
第三種,如果你用過jsvm框架的話就會發現裏面的代碼使用了這種形式。
那如何解釋第三種情況呢?
爲了弄明白瀏覽器是如何理解這樣的寫法的,我們可以利用一下Mozilla Firefox的錯誤控制檯功能。
在代碼中插入一段錯誤代碼,代碼段如下:
- (function(s){s+s}(1)).splice();
打開Mozilla Firefox的錯誤控制檯,可以看到有如下的錯誤提示
源文件:file:///C:/Documents…….html
行:18
可以認爲,瀏覽器對於
- (function(s){s+s}(1))
- (function (s) {s+s})(1)
到此可能你有這樣的認識:
- function f(x){return x*x;};f(x);==(function(x){return x*x;})(x);==(function(x){return x*x;}(x));
但是他們還是有區別的,
首先,對於像第二和第三種形式,其它的函數和代碼是不可能調用所定義的函數的,有一種說發把這樣的函數稱爲匿名函數或者函數直接量。
其次,第二和第三種形式執行的函數,中間變量不會污染到全局命名空間,你可以把中間的代碼看作純粹的子過程調用。
當然使用後面兩種形式的函數定義可以很容易的實現閉包。
看一個例子:
- /*
- http://jibbering.com/faq/faq_notes/closures.html(Dnew.CN注)
- A global variable - getImgInPositionedDivHtml - is declared and
- assigned the value of an inner function expression returned from
- a one-time call to an outer function expression.
- That inner function returns a string of HTML that represents an
- absolutely positioned DIV wrapped round an IMG element, such that
- all of the variable attribute values are provided as parameters
- to the function call:-
- */
- var getImgInPositionedDivHtml = (function(){
- /* The - buffAr - Array is assigned to a local variable of the
- outer function expression. It is only created once and that one
- instance of the array is available to the inner function so that
- it can be used on each execution of that inner function.
- Empty strings are used as placeholders for the date that is to
- be inserted into the Array by the inner function:-
- */
- var buffAr = [
- '<div id="',
- '', //index 1, DIV ID attribute
- '" style="position:absolute;top:',
- '', //index 3, DIV top position
- 'px;left:',
- '', //index 5, DIV left position
- 'px;width:',
- '', //index 7, DIV width
- 'px;height:',
- '', //index 9, DIV height
- 'px;overflow:hidden;/"><img src=/"',
- '', //index 11, IMG URL
- '/" width=/"',
- '', //index 13, IMG width
- '/" height=/"',
- '', //index 15, IMG height
- '/" alt=/"',
- '', //index 17, IMG alt text
- '/"><//div>'
- ];
- /* Return the inner function object that is the result of the
- evaluation of a function expression. It is this inner function
- object that will be executed on each call to -
- getImgInPositionedDivHtml( ... ) -:-
- */
- return (function(url, id, width, height, top, left, altText){
- /* Assign the various parameters to the corresponding
- locations in the buffer array:-
- */
- 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;
- /* Return the string created by joining each element in the
- array using an empty string (which is the same as just
- joining the elements together):-
- */
- return buffAr.join('');
- }); //:End of inner function expression.
- })();
- /*^^- :The inline execution of the outer function expression. */