2013-09-26 50 views
0

我想了解call()方法是如何工作的。我有以下我在Firebug Javascript控制檯中執行的代碼片段。Javascript調用()方法不產生預期的輸出

代碼:

var window = {num1: 10, num2: 20}; 
var o = {num1: 20, num2: 30}; 

var sum = function(num1, num2) { 
    return this.num1 + this.num2; 
}; 

console.log(sum.call(o)); // 50 
console.log(sum.call(window)); // 30 
console.log(sum.call(this)); // 30 

輸出:

50 
NaN 
NaN 

我期望的輸出爲50和30分別。當window/this對象作爲執行上下文傳遞時,爲什麼call()會返回NaN?

+5

'window'是瀏覽器中的保留字。您無法用變量覆蓋或隱藏它。 –

+5

而'this'指的是全局命名空間,它顯然沒有num1或num2成員。 –

+0

那麼,你可以用一個局部變量來遮蔽它 - '(function(){var window = {}; console.log(window)}());' - 但是當然你不能完全覆蓋它,你可以仍然可以通過執行類似'top.window'的方式在閉包中訪問它。 – Adam

回答

0

你在做什麼樣的環境測試? window是一個主機對象,充當所有瀏覽器中的全局對象。您無法在全局上下文中使用變量覆蓋它。

因此,當您撥打window時,您正在調用不具有num1或num2屬性的全局對象。如果你沒有

var num1 = 10, num2 = 20; 

你會得到你的日誌的預期值。

這是因爲在全局範圍中分配變量將它們指定爲窗口的屬性。

它的工作原理對於第三種情況,因爲this值在調用時確定的,而當你從全局代碼引用此,它指的是window對象。

2

聲明一個窗口變量將跨越當前範圍的窗口對象。這可能會導致意外的行爲(在我的瀏覽器中,firefox,我得到50,30,NaN)。更改第一行:

window.num1 = 10; window.num2= 20; 

將分配NUM1和NUM2全局窗口屬性(不是一個好主意)。

在另一個說明中,調用將第一個參數作爲上下文(this)進行傳遞。函數聲明中的參數是不必要的。如果你想傳遞一個陣列,您指定參數時,使用的申請,e.g:

var myArgs = [10, 20]; 
sum.apply(window, myArgs); 

,你將不得不從你的函數體刪除此預選賽爲它添加了通過ARGS。