this關鍵字是JavaScript中最複雜的機制之一。是一個很特別的關鍵字,被定義在所有函式的作用域中。
那麼,我們為什麼要使用this
function identify() {
return this.name.toUpperCase();
}
function speak() {
var greeting = 'Hello,I am' + identify.call(this);
console.log( greeting )
}
var you = {
name: 'Tom'
}
var me = {
name: 'Jerry'
}
identify.call( me ); // Jerry
identify.call( you ); //Tom
speak.call( me ); // Hello I am JERRY
speak.call( you ); // Hello I am TOM
複製程式碼
以上程式碼看不懂不要緊,現在需要知道的就是 this 隱式傳遞了一個物件引用
,注意:一般我們是顯式的傳遞上下文物件,這會讓我們的程式碼變得越來越混亂,使用this則不會這樣,自動引用合適的上下文是至關重要的。
消除誤解
有兩種常見的解釋,但他們都是錯誤的
指向自身?
英語語法裡,this確實是指向自身,貌似是說的通的,
不過,我們看下面的一個例子
function foo(num) {
console.log( "foo: " + num );
this.count++;
}
foo.count = 0;
var i;
for(let i=0; i<10; i++) {
if(i > 5) {
foo(i)
}
}
console.log( foo.count ); // 0
複製程式碼
那麼結果是什麼呢? foo:6
foo:7
foo:8
foo:9
事實上,foo函式確實被呼叫了4次,但是 foo.count 還是0!
說明:this指向自身,是錯誤的。
當執行foo.count = 0
,是向foo新增了count屬性,值為0,不過,函式內部的this並不指向那個函式物件
當然,很多開發者並不會試圖去解決這些“艱難而且重要”的問題。而是迴避,比如,再建立一個帶有count屬性的物件。
function foo(num) {
console.log( "foo: " + num );
data.count++;
}
var data = {
count = 0
}
var i;
for(let i=0; i<10; i++) {
if(i > 5) {
foo(i)
}
}
// foo:6
// foo:7
// foo:8
// foo:9
console.log( foo.count ); // 4
複製程式碼
問題解決了!但是卻沒有解決真正的問題---this的含義以及工作原理。
以上為從物件內部引用自身,只是用 this 是不夠的,一般需要一個指向函式物件的變數引用它
函式分兩種:具名函式 和 匿名函式
//具名函式 內部可以用函式名引用自身
function foo(){
foo.count = 4;//foo 指向自身
}
setTimeout( function(){
//匿名函式,無法指向自身
},10);
複製程式碼
指向它的作用域?
這種認識在某種情況下是正確的,但是其他情況下就全是錯誤的。
this在任何情況下都不指向函式的詞法作用域。雖然在js內部,作用域和物件比較相似,但是作用域無法通過js程式碼訪問,只存在於js引擎內部。
經典的錯誤!
function foo(){
var a = 2;
this.bar();
}
function bar(){
console.log( this.a );
}
foo();//ReferenceError
複製程式碼
this 到底指什麼???
接下來會繼續與大家探討 this 劍指何方。