前言:js中常常會看到this.,在不理解this的時候就會形成this的「濫用」,致使開發過程當中須要花費大量的時間查找由於this的指向問題致使的bug。但願經過本文可以讓你們理解this,節省你們開發時間。javascript
this是當前執行代碼的環境對象,若是在非嚴格模式下,老是指向一個對象;若是在嚴格模式下,能夠是任意值。 在不一樣的狀況下this的指向也有所不一樣,接下來咱們看一下幾種不一樣狀況下this的指向。前端
全局環境中,this指向全局對象(本文只討論在瀏覽器環境,不討論nodejs):java
console.log(this === window); // true
複製代碼
函數環境中,this的值取決於函數被調用的方式,也能夠理解爲函數由誰調用,this就指向誰:node
function f1() {
return this;
}
console.log(f1() === window); // true
複製代碼
f1()調用的時候至關於window.f1(),這裏是省略了window。瀏覽器
當函數做爲對象中的方法被調用時,this是調用該函數的對象:markdown
var user = {
age: 31,
getAge: function() {
return this.age;
}
}
console.log(user.getAge()); // 31
複製代碼
this是在getAge函數中,getAge又是被user調用,因此getAge中的this就指向了user,this.age也就是user.age。app
若是this所在的方法存在於原型鏈中,那麼this也是指向該方法的調用對象:函數
var util = {
sum: function() {
return this.a + this.b;
}
};
var _util = Object.create(util);
_util.a = 1;
_util.b = 2;
console.log(_util.sum()); // 3
複製代碼
當一個函數用做構造函數時(使用new關鍵字),它的this被綁定到正在構造的新對象:學習
function userConstructor() {
this.age = 33;
}
var user3 = new userConstructor();
console.log(user3.age); // 33
function userConstructor2() {
this.age = 34;
return {
age: 35
}
}
var user4 = new userConstructor2();
console.log(user4.age); // 35
複製代碼
對於user3.age這個很好理解,而user4中構造函數裏直接返回了一個對象,這裏若是構造函數中直接返回一個對象,那麼經過new關鍵字建立出來的對象就是return的那個值,因此user.age值爲35。ui
箭頭函數中,this與封閉詞法環境的this保持一致:
var user4 = {
name: 'tom',
age: 20,
getName() {
console.log(this.name);
},
getAge: () => {
console.log(this.age);
}
}
user4.getName(); // tom
user4.getAge(); // undefined
複製代碼
getName不是用的箭頭函數,因此getName中的this指向該函數的調用者user4,this.name也就至關於user4.name;
可是getAge是一個箭頭函數,它裏面的this指向該函數所在的做用域,根據做用域相關的知識能夠知道getAge應該在全局環境中,因此this指向window,這裏假設全局環境沒有age變量,因此this.age的值就爲undefined。
雖然this的指向有必定的規則,可是咱們也能夠主動的修改它的指向,如下三種方法能夠修改this:
- call
- apply
- bind
這三種方法能夠指定this,具體怎麼使用就再也不多說,你們能夠自行搜索學習。
this的指向是前端的一個比較很差理解的知識點,可是一旦理解了this,對咱們在平時開發過程當中有很大的幫助,可以減少項目出現bug的概率,節省開發時間。