this 全面解析(一)

this關鍵字是JavaScript中最複雜的機制之一。是一個很特別的關鍵字,被定義在全部函數的做用域中。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則不會這樣,自動引用合適的上下文是相當重要的。java

消除誤解

有兩種常見的解釋,但他們都是錯誤的ide

指向自身?

英語語法裏,this確實是指向自身,貌似是說的通的,函數

不過,咱們看下面的一個例子ui

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:6this

foo:7spa

foo:8code

foo:9對象

事實上,foo函數確實被調用了4次,可是 foo.count 仍是0!ip

說明: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 劍指何方。

相關文章
相關標籤/搜索