本文是翻譯的繁體文章,而且還不完整,盡量讀原文吧:https://software.intel.com/zh-cn/blogs/2013/10/09/javascript-this
注意:搞過java,c#和c++的人千萬不能照搬以前的知識
this是執行上下文的一個屬性,而不是變量對象的一個屬性或者說是代表類的目前執行個體。再白話一點,看調用的上下文環境是什麼才能決定this在執行的那一刻到底代表什麼。
一、this指向調用該函數的對象
文法:
對象.方法名(); //這種情況下函數或者方法内的this代表這個對象
示例:
var obj = {
x: 20,
f: function(){ console.log(this.x); }
};
obj.f(); //調用f函數的時候,點前面的對象是obj,是以f函數内的this指向obj,輸出結果是20
obj.innerobj = {
x: 30,
f: function(){ console.log(this.x); }
}
obj.innerobj.f(); //由于調用f函數時,點前面的對象是obj.innerobj,是以f函數内的this指向innerobj,輸出結果是30
二、this指向全局對象
文法:
函數名稱([參數]);//函數内的this關鍵字指向預設浏覽器的window對象
示例:
var x = 10;
var f = function(){
console.log(this.x);
};
f(); //由于調用f函數時,沒有指明[對象.]的形式,是以f函數内的this在執行時指向全局對象,即window,是以輸出10
深入了解示例1:
var x = 10;
var obj = {
x: 20,
f: function(){
console.log(this.x);
var foo = function(){ console.log(this.x); }
foo(); // (2)
}
};
obj.f(); // (1)
如果你認為上面的代碼應該輸出20,20的話就還是沒有轉換為js的思考方式考慮問題(還是java的思路呢),記住是誰調用或者說誰執行就是誰的,(1)位置的代碼是obj.f()調用的,第一次的console.log(this.x)的時候this就是obj,是以輸出20,第二次的(2)位置的代碼是沒有指明調用對象是誰,就是直接用foo()調用的,屬于全局對象調用方式,則foo函數裡面的this.x指向window.x,是以輸出10。
要是想輸出20,20應該怎麼寫呢?得把指向obj的this存起來,然後在後面的代碼裡面去使用,示例如下:
var x = 10;
var obj = {
x: 20,
f: function(){
console.log(this.x);
var me=this;
var foo = function(){ console.log(me.x); }
foo(); // (2)
}
};
obj.f(); // (1)
另外一個示例:
var x = 10;
var obj = {
x: 20,
f: function(){ console.log(this.x); }
};
obj.f(); // (1)
var fOut = obj.f;
fOut(); //(2)
var obj2 = {
x: 30,
f: obj.f
}
obj2.f(); // (3)
(1)位置的代碼是obj.去調用的,是以執行的時候this代表obj,輸出20
(2)位置的代碼是全局調用的方式,沒有指明是哪個對象,那麼執行的時候this指向window,輸出10