2014-05-09 27 views
2

請看下面的代碼並解釋:我做錯了什麼?我不明白JavaScript中call()方法的要點

 

    function doStuff(a, b){ 
     return a + b + 1 ; 
    } 

    var myContext = { 
     c: 1, 
     d: 3 
    }; 

// myContext = this (result => 5) 
    doStuff.call(myContext,myContext.c,myContext.d) 

// ... so why doesn't the below work? (result => NaN) 
    doStuff.call(myContext,this.c,this.d) 

// To make the above work, i must replace "this" with "myContext" (result => 5)... 
    doStuff.call(myContext,myContext.c,myContext.d) 

// ...which is no different to... 
    doStuff(myContext.c,myContext.d) 

// ...so what was the point of call() method? 

我是厚厚的嗎?

+1

'Function.prototype的.call()在函數內部設置this,所以如果你有函數doStuff(){return this.a + this.b + 1}',你可以執行'doStuff.call(myContext);' – raser

+0

函數*這個*是一個參數是其[*執行上下文*](http://ecma-international.org/ecma-262/5.1/#sec-10.3)的一部分,它本身不是「上下文」。 – RobG

回答

3

call的要點是設定值this的範圍內的功能。由於您的doStuff不使用this以內的功能,使用call與它是毫無意義的。

這裏就是它的問題的例子:

function doStuff(a, b) { 
    return this.sum(a, b); 
} 
var obj = { 
    sum: function(a, b) { 
     return a + b; 
    } 
}; 
console.log(doStuff.call(obj, 3, 4)); // 7, because `obj` has a `sum` property 
console.log(doStuff(3, 4));   // Fails with an error that `this.sum` is not a function 

那麼,爲什麼下面的工作? (結果=> NAN)

doStuff.call(myContext,this.c,this.d)

由於this.c被呼叫之前評估doStuff,使用任何當前this值。您可能會調用該代碼,this是(在鬆散模式下)全局對象(窗口對象,在瀏覽器上),它可能沒有cd屬性。 (在嚴格模式下,再次做出關於你如何調用一個假設,你會得到一個例外,因爲thisundefined,你不能從undefined檢索屬性。)

+1

現在有道理。乾杯。 – neahan

0

.call.apply是功能方法'操縱'什麼this意味着在一個函數內。

doStuff.call(myContext, myContext.c, myContext.d): 這裏您已經設置myContext作爲上下文doStuff功能 ,你可以參考它裏面用this, ,你已經通過兩個參數是:myContext.c,myContext.d, 它的工作原理就像你打算......


doStuff.call(myContext, this.c, this.d): 再次myContext是上下文doStuff() 你已經通編輯.c.d什麼this指向 屬性在您的情況下出現(全局對象,窗口)的上下文中。 所以doStuff的背景是myContext,和參數是2個undefined S, 因爲this === window在上下文中,你調用的函數, 和要傳遞的global.c.d性能到功能。 你實際上得到這個:return undefined + undefined + 1;(NAN)


如果重新定義 'doStuff' 這樣的:

function doStuff() { 

    return this.a + this.b + 1; 

    // here it looks whatever this is set to 
    // by `.call()` or `.apply()` methods 

} 

,並調用它像這樣:

var sum = doStuff.call(myContext); 

// notice that using `.call` here 
// means that 'myContext' is manualy set 
// as `this` value inside the function above 
// and is refered to by dynamic variable 'this'