2013-03-11 64 views
2

我碰到這個代碼,不明白爲什麼代碼塊中的代碼被封裝在像自動執行函數一樣的parens中。塊內的代碼被包裝在parens裏面。爲什麼?

function foo(a,b) { 
    var b = b || window, 
    a = a.replace(/^\s*<!(?:\[CDATA\[|\-\-)/, "/*$0*/"); 
    if (a && /\S/.test(a)) { 
    (b.execScript || function (a) { 
     b["eval"].call(b, a) 
    })(a); 
    } 
} 

第一個參數是來自腳本標記的文本。我沒有得到的唯一部分是爲什麼腳本eval被包裹在parens中。

回答

5

我假設你是在談論這一部分:

(b.execScript || function (a) { 
    b["eval"].call(b, a) 
})(a); 

這是寫作的縮寫形式:

if (b.execScript) { 
    b.execScript(a); 
} 
else { 
    b["eval"].call(b, a); 
} 

即如果已定義則執行b.execScript,否則請致電b["eval"].call(b, a)

分組操作符的用途是在函數調用之前評估... || ...,即無論分組操作符的結果如何,它都被視爲函數並通過傳遞a來調用它。

它看起來像代碼可以簡化爲

(b.execScript || b["eval"])(a); 

但如果明確設置thisb是必要的,那麼函數表達式是必要的,也是,有兩個函數只接受一個參數,a

+0

...除非不需要在非窗口'b'的上下文中調用'eval'。 – VisioN 2013-03-11 15:15:42

+0

也許,我沒有真正看過代碼應該做什麼。 – 2013-03-11 15:16:31

+0

從某種程度上看,來自jQuery VisioN 2013-03-11 15:24:23

2

因爲之後有(a)。表達式:

(b.execScript || function (a) { 
     b["eval"].call(b, a) 
    }) 

返回封閉,然後與a作爲參數傳遞執行。

3

由於||運算符的綁定比函數調用運算符()更鬆散,所以加括號。如果沒有圓括號,彷彿它被寫入的表達式將被評估:

b.execScript || (function (a) { b["eval"].call(b, a); })(a) 

即,它會是任一的b.execScript平原值或調用該函數的值。作者想要的是調用b.execScript(這可能是一個函數)的值那個小的匿名函數。

4
(b.execScript || function (a) { 
     b["eval"].call(b, a) 
    })(a) 

因爲||語句需要進行評估,以確定哪些功能被傳遞參數之前運行這個被包裹在括號。

此代碼調用b.execScript與參數a如果b.execScript存在,並且是truthy。否則它會定義一個新函數並將a作爲參數傳遞給它。

parens wrap是爲了確保||語句在函數執行前被評估。沒有它,如果b.exec不存在,那麼邏輯基本上會執行,評估爲自定義函數的值,如果是,則評估爲b.exec。

於是用括號的邏輯等價於:

if(b.execScript){ 
    b.execScript(a) 
} 
else{ 
    function (a) { 
    b["eval"].call(b, a) 
    })(a) 

} 

沒有它,其相當於

如果(b.execScript!){ 函數的(a){ B [「EVAL 「] .CALL(b,A) })(一) }

0

括號表達式返回b.execScript的結果或一個新函數。無論哪種情況,結果都會以參數的形式被調用。 parens確保解釋器評估||在調用之前。

0

爲什麼代碼塊中的代碼被封裝在parens中,就像自動執行函數一樣。

由於代碼的該特定部分是自動執行功能:

(b.execScript || function (a) { 
    b["eval"].call(b, a) 
})(a); 

這裏,變量b參照執行容器,例如windowa包含需要執行的JavaScript代碼。

由於一些瀏覽器支持execScript()而有些只支持eval(),代碼通過測試該瀏覽器的功能,像這樣支持他們兩個:

var tmp = b.execScript || function (a) { 
    b["eval"].call(b, a) 
}; 

這裏,tmp是一個函數,它接受一個參數a並執行內的代碼;如果execScript不可用,則使用小型輔助函數。然後,它被稱爲是這樣的:

tmp.call(b, a); 

.call()的第一個參數定義了this是指當tmp被調用;第二個參數成爲tmp的第一個參數。

相關問題