2012-10-03 15 views
4

在下面的代碼中,第一個函數沒有綁定到obj,但第二個函數是,所以f()返回fifig()返回Mark Twain如預期。但第三次嘗試,首先是(obj.getCallBack),現在是一個函數,然後調用它,本質上它應該與f的情況相同。但他們確實打印出Mark Twain。爲什麼他們沒有使用bind()綁定到obj,但仍然執行this指向obj在Javascript上,爲什麼沒有使用bind()綁定的函數仍然綁定到對象?

(第4次嘗試只是方法的一般調用,而this應該綁定到調用該方法的對象)。

(在目前的Chrome,Firefox和IE 9測試)

window.name = "fifi"; 

var obj = { 
    name: "Mark Twain", 
    getCallBack: function() { 
     return this.name; 
    } 
} 

var f = obj.getCallBack; 
var g = f.bind(obj); 

console.log(f); 
console.log(f()); 

console.log(g); 
console.log(g()); 

console.log((obj.getCallBack)()); 
console.log(obj.getCallBack()); 

回答

4

您忘記了,如果一個函數被調用一些對象的屬性,則該對象將是this用於呼叫。所以:

obj.getCallBack() //The function referenced by `obj.getCallBack` 
        //is called as a property of `obj`, so obj will be `this` 
        //for the call 

f() //The function referenced by f, is not called as a property of some object so 
     //`this` will depend on strict mode. 

這些基本規則後,綁定功能將被調用,它可以(任何墊片做到這一點),被認爲是一個代理功能使用.call/.apply明確設定爲目標函數的上下文。所以代理函數的this值並不重要,但在幕後它是由基本規則設置的。

編輯:

(obj.getCallBack)does not return the function as value, because getValue is not called.。所以它與obj.getCallback完全一樣,第一篇文章適用。

所以,你可以做到這一點,並沒有得到一個錯誤:

(obj.getCallback) = 5; 

至於反對:

(function(){}) = 5; //invalid assignment 
+0

但我認爲當使用'(obj.getCallBack)'時,它只是表示一個函數,而沒有評估過「this」是什麼。也就是說,它只是函數的靜態文本定義。所以我的意思是,'這'是作爲文本,但沒有評估。然後當使用'()'調用時,它將作爲函數調用。除非你說'this'被評估,那麼這應該意味着'this.name'也被評估了,所以它應該已經是'Mark Twain'了。 –

+0

@動靜能量'(obj.fn)()'和'obj。fn()'是一回事。 '(obj.fn)()' - >'obj.fn()' - >函數被稱爲'obj.'的屬性' – Esailija

+0

'console.log(f ===(obj.getCallBack) );'會打印出真實的,而調用它們會得到不同的結果。也許比較不考慮約束力 –

0

爲了補充Esailija的回答,預期的效果實際上應該是:

var obj = { 
    name: "Mark Twain", 
    getCallBack: function() { 
     return function() { return this.name; }; 
    } 
} 

var f = obj.getCallBack(); 
var g = f.bind(obj); 

console.log(f); 
console.log(f()); 

console.log(g); 
console.log(g()); 

console.log((obj.getCallBack())()); 
console.log(obj.getCallBack()()); 

console.log(obj.getCallBack().bind(obj)()); 

然後在這種情況下,第三次嘗試將給出fifi,第四次嘗試PT。要獲得obj中的名稱,第五次嘗試將其綁定並調用它並獲得Mark Twain

但返回的回調函數應該綁定它,讓我們的代碼更改爲方法:

var obj = { 
    name: "Mark Twain", 
    getCallBack: function() { 
     return (function() { return this.name;}).bind(this); // <-- note here 
    } 
} 

,現在所有的嘗試,甚至f(),將返回Mark Twain

相關問題