2012-06-07 38 views
3

我從MDN文檔說的。適用和.CALL第一個參數是「這個」對象讀取,但瞭解.CALL的行爲。適用在Javascript

var stringToEval = "console.log(this)"; 
eval.call(null, stringToEval); 
eval.apply(null, [stringToEval]); 

在上述兩個密碼行最終會記錄Window對象(在瀏覽器中)。它不應該記錄爲空,這是我作爲第一個參數在兩個方法中傳遞?

回答

1

MDN

的這個規定的呼叫樂趣的值。請注意,這可能不是該方法看到的實際值:如果該方法是非嚴格模式代碼中的函數,則null和undefined將被全局對象替換,並且原始值將被裝箱。

全局對象是窗口。

編輯因爲無論您傳遞null,undefined還是帶有eval的對象都沒有關係。在eval內,this將與eval呼叫之前的this相同。

根據ECMA-262 5.1的第15.1.2.1節,eval接受一個字符串並將其解析爲ECMAscript。如果它是有效的ECMAscript,那麼它在它被調用的上下文中運行它。所以在你的情況下,你可以考慮eval的調用,就好像它們在運行時用console.log(this)代替它們一樣。與更換你最終方案:

var stringToEval = "console.log(this)"; 
console.log(this); 
console.log(this); 

這使得它很清楚,爲什麼它輸出DOMWindow對象兩次。讓您可以這樣說:

var stringToEval = "console.log(this)"; 
(function(str){ eval(str); }).call({not: "empty"}, stringToEval); 
(function(str){ eval(str); }).apply({not: "empty"}, [stringToEval]); 

從什麼時候開始的eval與console.log(this)替換本身這將是在匿名函數中this將參考傳入的對象的上下文

See this JSFiddle

+1

好,VAR stringToEval = 「執行console.log(本)」; eval.call({},stringToEval); eval.call(「」,stringToEval); eval.call({not:「empty」},stringToEval);仍然全部返回窗口對象...它不是null或undefined了... –

+1

您的jsfiddle在Chrome和Firefox中爲我返回Window ... –

+0

這是間接eval調用,'this'將始終是'window'。它與'.call'或'無關。申請' – Esailija

0

您打電話eval明確設置thisnull,這與this對象將在撤回 代碼內無關,無處我是t表示eval評估代碼與this設置爲相同的this,你稱爲eval與。實際上,這樣做是調用evalindirectly並導致eval代碼在全球上下文中爲現代瀏覽器運行。

因此,你想與正常功能測試:

function test() { 
    console.log(this); 
} 

test.call({}); 
test.apply({});