大前端學習筆記整理【五】關於JavaScript中的關鍵字——this

寫在前面

工做有那麼一段時間了,可是在工做中,發現本身的理論知識仍是有所欠缺。特別是在javascript上,不少東西其實本身屬於知道要用這個,可是不知道爲何要這麼用...這種狀況非常尷尬了,因此寫博客的很重要一個目的就是鍛鍊我本身的總結能力,把學到的東西總結出來,感受這樣能讓我更快的去理解所學到的東西。javascript

◇ 關於javascript理論

剛開始作前端的時候仍是以完成功能爲主,因此忽略掉了理論知識的重要性,可是隨着工做的慢慢深刻,發現不少原理仍是要創建在對理論知識的理解與掌握上。前端

做爲一個合格的前端工程師,這個確實有點不能忍...因此仍是要沉下心來,一點點的去提高本身。話說回來,其實javascript的理論在我看來並無那麼的枯燥難懂,可是須要你去實驗、去調試。興趣永遠是學習最好的動力,我想保持這份興趣,持續的去研究javascript的理論,去探尋其中的祕密和讓人驚歎的地方。java

 

關於this

閒話扯了那麼多,但願各位看官不要在乎...只是本人一點點心聲罷了...言歸正傳,關於this,其實在我看來確實算是javascript中很基礎、很重要、也是很難理解的一個點;數組

this的定義,藉助下阮一峯大大的總結,感受比較好理解些:瀏覽器

this是Javascript語言的一個關鍵字。
它表明函數運行時,自動生成的一個內部對象,只能在函數內部使用。好比,
function test(){
  this.x = 1;
}
隨着函數使用場合的不一樣,this的值會發生變化。可是有一個總的原則,那就是this指的是,調用函數的那個對象。

this的指向

其實this之因此難以理解,主要就是在不一樣狀況下,this的指向都是不同的。如下幾種狀況,基本概括了常見的this的指向:前端工程師

1.在全局代碼或者普通的函數調用中,this指向全局對象,在瀏覽器裏面既爲window對象。
console.log(this);//輸出window 

function foo(){ 
    console.log(this); 
} 
foo();//輸出window
在瀏覽器環境裏運行上述代碼,兩處輸出結果均爲window對象。
 
2.經過call或apply方法調用函數,this指向方法調用的第一個參數。
var obj = {name:'test'}; 
function foo(){ 
    console.log(this); 
} 
foo.call(obj);//輸出obj 
foo.apply(obj);//輸出obj
call和apply的區別在於call的調用須要兩個參數,用逗號作分割,而apply只須要一個參數,這個參數必須是數組;
 
插入的小知識點:
利用apply的特色實現不建立新的對象把兩個數組拼裝成一個數組:
var arr1 = [1, 2 , 3], 
    arr2 = [4, 5, 6]; 
Array.prototype.push.apply(arr1, arr2); 
console.log(arr1);//輸出[1, 2, 3, 4, 5, 6]

call與apply的定義:

call方法: 

語法:call(thisObj,Object)
定義:調用一個對象的一個方法,以另外一個對象替換當前對象。
說明:
call 方法能夠用來代替另外一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變爲由 thisObj 指定的新對象。 
若是沒有提供 thisObj 參數,那麼 Global 對象被用做 thisObj。 
 
apply方法: 
語法:apply(thisObj,[argArray])
定義:應用某一對象的一個方法,用另外一個對象替換當前對象。 
說明: 
若是 argArray 不是一個有效的數組或者不是 arguments 對象,那麼將致使一個 TypeError。 
若是沒有提供 argArray 和 thisObj 任何一個參數,那麼 Global 對象將被用做 thisObj, 而且沒法被傳遞任何參數
 
3.調用對象的方法,this指向該對象。
var obj = {name:'test'};
 function foo(){ 
    console.log(this); 
} 
obj.foo = foo; obj.foo();//輸出obj
這個也就是所謂的誰調用,指向誰
 
4.構造方法中的this,指向新構造的對象。
function C(){ 
    this.name = 'test'; 
    this.age = 18; 
    console.log(this); 
} 
var c = new C();//輸出 c 
console.log(c);//輸出 c
執行以上代碼後,控制檯輸出均爲c所指向的對象。當new操做符用於函數時,會建立一個新對象,並用this指向它
 

特殊狀況

上述四種狀況基本概述了this的常見指向,可是也有些特殊的狀況下,this的指向並不在上訴的範圍中:app

a.bind方法

這個方法會建立一個函數實例,其this值會被綁定到傳給bind()函數的值。也就是說會返回一個新函數,而且使函數內部的this指向爲傳入的第一個參數:函數

 

window.color = 'red';
var o = {color : 'blue'};
function sayColor(){
    alert(this.color)
}
var objectSayColor = sayColor.bind(o);
objectSayColor();//blue

 

 

b.eval學習

對於eval函數,其執行時候彷佛沒有指定當前對象,但實際上其this並不是指向window,由於該函數執行時的做用域是當前做用域,即等同於在該行將裏面的代碼填進去。下面的例子說明了這個問題:this

var name = "window";

var Bob = {
    name: "Bob",
    showName: function(){
        eval("alert(this.name)");
    }
};

Bob.showName();

 

總結

  • 默認的,this指向全局對象
  • 當一個函數被做爲一個父對象的屬性調用時,函數中的this指向父對象
  • 當一個函數被new運算符調用時,函數中的this指向新建立的對象
  • 當使用call或apply調用函數時,函數代碼中的this被設置爲call或apply中的第一個參數。若是第一個參數是null或不是個對象,this指向全局對象。

其實除去上面的特殊狀況,咱們只要記住這四種狀況,那麼對於this的指向應該就有一個較爲清楚的認識。

 

博文中若有敘述不清或者錯誤,歡迎各位批評指正!完結撒花~

相關文章
相關標籤/搜索