Javascript中this關鍵字詳解
原文地址
Quiz
請看下面的程式碼,最後alert出來的是什麼呢?
var name = "Bob";
var nameObj ={
name : "Tom",
showName : function(){
alert(this.name);
},
waitShowName : function(){
setTimeout(this.showName, 1000);
}
};
nameObj.waitShowName();
要解決這個問題我們需要了解Javascript的this關鍵字的用法。
this指向哪裡?
一般而言,在Javascript中,this指向函式執行時的當前物件。
In JavaScript, as in most object-oriented programming languages, this is a special keyword that is used within methods to refer to the object on which a method is being invoked.
——jQuery Fundamentals (Chapter 2), by Rebecca Murphey
值得注意,該關鍵字在Javascript中和執行環境,而非宣告環境有關。
The this keyword is relative to the execution context, not the declaration context.
我們舉個例子來說明這個問題:
var someone = {
name: "Bob",
showName: function(){
alert(this.name);
}
};
var other = {
name: "Tom",
showName: someone.showName
}
other.showName(); //Tom
this關鍵字雖然是在someone.showName中宣告的,但執行的時候是other.showName,所以this指向other.showName函式的當前物件,即other,故最後alert出來的是other.name。
沒有明確的當前物件時
當沒有明確的執行時的當前物件時,this指向全域性物件window。
By default, this refers to the global object.
為什麼說是全域性物件(the global object),因為非瀏覽器情況下(例如:nodejs)中全域性變數並非window物件,而就是叫“全域性變數”(the global object)。不過由於我們這片文章主要討論的是前端開發知識,所以nodejs就被我們忽略了。
例如對於全域性變數引用的函式上我們有:
var name = "Tom";
var Bob = {
name: "Bob",
show: function(){
alert(this.name);
}
}
var show = Bob.show;
show(); //Tom
你可能也能理解成show是window物件下的方法,所以執行時的當前物件時window。但區域性變數引用的函式上,卻無法這麼解釋:
var name = "window";
var Bob = {
name: "Bob",
showName: function(){
alert(this.name);
}
};
var Tom = {
name: "Tom",
showName: function(){
var fun = Bob.showName;
fun();
}
};
Tom.showName(); //window
setTimeout、setInterval和匿名函式
文章開頭的問題的答案是Bob。
在瀏覽器中setTimeout、setInterval和匿名函式執行時的當前物件是全域性物件window,這條我們可以看成是上一條的一個特殊情況。
所以在執行this.showName的時候,this指向了window,所以最後顯示了window.name。
瀏覽器中全域性變數可以當成是window物件下的變數,例如全域性變數a,可以用window.a來引用。
我們將程式碼改成匿名函式可能更好理解一些:
var name = "Bob";
var nameObj ={
name : "Tom",
showName : function(){
alert(this.name);
},
waitShowName : function(){
!function(__callback){
__callback();
}(this.showName);
}
};
nameObj.waitShowName(); //Bob
**在呼叫nameObj.waitShowName時候,我們執行了一個匿名函式,將nameObj.showName作為回撥函式傳進這個匿名函式,然後匿名函式執行時,執行這個回撥函式。由於匿名函式的當前物件是window,所以當在該匿名函式中執行回撥函式時,回撥函式的this指向了window,所以alert出來window.name。
由此看來setTimeout可以看做是一個延遲執行的:
function(__callback){
__callback();
}
setInterval也如此類比。
但如果我們的確想得到的回答是Tom呢?通過一些技巧,我們能夠得到想要的答案:
var name = "Bob";
var nameObj ={
name : "Tom",
showName : function(){
alert(this.name);
},
waitShowName : function(){
var that = this;
setTimeout(function(){
that.showName();
}, 1000);
}
};
nameObj.waitShowName(); //Tom
在執行nameObj.waitShowName函式時,我們先對其this賦給變數that(這是為了避免setTimeout中的匿名函式執行時,匿名函式中的this指向window),然後延遲執行匿名函式,執行that.showName,即nameObj.showName,所以alert出正確結果Tom。
eval
對於eval函式,其執行時候似乎沒有指定當前物件,但實際上其this並非指向window,因為該函式執行時的作用域是當前作用域,即等同於在該行將裡面的程式碼填進去。下面的例子說明了這個問題:
var name = "window";
var Bob = {
name: "Bob",
showName: function(){
eval("alert(this.name)");
}
};
Bob.showName(); //Bob
apply和call
apply和call能夠強制改變函式執行時的當前物件,讓this指向其他物件。因為apply和call較為類似,所以我們以apply為例:
var name = "window";
var someone = {
name: "Bob",
showName: function(){
alert(this.name);
}
};
var other = {
name: "Tom"
};
someone.showName.apply(); //window
someone.showName.apply(other); //Tom
apply用於改變函式執行時的當前物件,當無引數時,當前物件為window,有引數時當前物件為該引數。於是這個例子Bob成功偷走了Tom的名字。
new關鍵字
new關鍵字後的建構函式中的this指向用該建構函式構造出來的新物件:
function Person(__name){
this.name = __name; //這個this指向用該建構函式構造的新物件,這個例子是Bob物件
}
Person.prototype.show = function(){
alert(this.name);
}
var Bob = new Person("Bob");
Bob.show(); //Bob
相關文章
- JavaScript中this關鍵字JavaScript
- javascript中的with關鍵字JavaScript
- C/C++中extern關鍵字詳解C++
- C/C++中volatile關鍵字詳解C++
- 完全理解JavaScript中的this關鍵字JavaScript
- JavaScript this關鍵字JavaScript
- [JavaScript] this 關鍵字JavaScript
- 萬字乾貨|Synchronized關鍵字詳解synchronized
- Python關鍵字yield詳解Python
- Python 關鍵字 yield 詳解Python
- javascript的this關鍵字JavaScript
- 詳解C++的模板中typename關鍵字的用法C++
- 詳解 C++ 的模板中 typename 關鍵字的用法C++
- C++ typeid關鍵字詳解C++
- C語言中static關鍵字詳解C語言
- c# yield關鍵字原理詳解C#
- 揭祕JavaScript中“神祕”的this關鍵字JavaScript
- Javascript中的關鍵字'this'學習筆記JavaScript筆記
- 關鍵字引數與非關鍵字引數(可變引數)詳解
- 淺顯易懂的理解JavaScript中的this關鍵字JavaScript
- JavaScript 複習之 this關鍵字JavaScript
- JavaScript 關鍵字和保留字JavaScript
- javascript 作用域和 this 關鍵字JavaScript
- Java 10 var關鍵字詳解和示例教程Java
- java中this關鍵字Java
- JavaScript 搜尋關鍵字高亮效果JavaScript
- javascript搜尋關鍵字高亮效果JavaScript
- javascript new關鍵字做了什麼JavaScript
- javascript實現關鍵字高亮(轉)JavaScript
- Python 關鍵字global全域性變數詳解Python變數
- java關鍵字詳解(abstract.double.int.switch) (轉)Java
- 用自然語言的角度理解JavaScript中的this關鍵字JavaScript
- JAVA中的關鍵字Java
- jQuery搜尋框關鍵字自動匹配提示詳解jQuery
- JavaScript的關鍵字和保留字大全JavaScript
- mysql 中的explain關鍵字MySqlAI
- Java中final關鍵字Java
- Java中this與super關鍵字Java