實(shí)習(xí)期間寫代碼時候就感覺this很迷。有些不知所措。后來查看了部分文章。
this最終指向的是調(diào)用它的對象(這個已經(jīng)理解了大部分了)
-
為什么要用this ? 為什么需要花費(fèi)時間進(jìn)行學(xué)習(xí)。
答:this 提供了一種更優(yōu)雅的方式來隱式“傳遞”一個對象引用,因此可以將 API 設(shè)計 得更加簡潔并且易于復(fù)用。隨著你的使用模式越來越復(fù)雜,顯式傳遞上下文對象會讓代碼變得越來越混亂,使用 this 則不會這樣。
-
this的誤區(qū)?
- 不是指向自身
- 第二種常見的誤解是,this 指向函數(shù)的作用域 (分情況)
-
this是什么?
this 是在運(yùn)行時進(jìn)行綁定的,并不是在編寫時綁定,它的上下文取決于函數(shù)調(diào) 用時的各種條件。this 的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)的調(diào)用方式。
當(dāng)一個函數(shù)被調(diào)用的時候,會創(chuàng)建一個活動記錄(有時候稱為執(zhí)行上下文)。這個記錄會包含函數(shù)在哪里調(diào)用(調(diào)用棧)、函數(shù)的調(diào)用方法、傳入的參數(shù)信息等。this就是記錄的其中一個屬性,會在函數(shù)執(zhí)行過程中用到。
-
this到底是什么?
this 實(shí)際上是在函數(shù)被調(diào)用時發(fā)生的綁定,它指向什么完全取決于函數(shù)在哪里被調(diào)用
-
全面解析this
-
理解調(diào)用位置。調(diào)用位置就是函數(shù)在代碼中被調(diào)用的 位置(而不是聲明的位置)
-
默認(rèn)綁定
獨(dú)立函數(shù)調(diào)用。不帶任何修飾的函數(shù)引用進(jìn)行調(diào)用的,只能使用默認(rèn)綁定。
-
隱式綁定
調(diào)用位置是否有上下文對象,或者說是否被某個對象擁有或者包含。
// 第一個例字 function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2 // 第二個例子 { let name = "sww_window"; let obj = { "name":"sww", "fn":function(){ console.log(this.name); } } obj.fn(); // sww let obj1 = obj.fn; obj1(); //undefined // 將let name 更換成 var name obj(); //輸出為sww_window 原因 let 默認(rèn)不掛在window上面 } -
顯式綁定
就是call apply bind call和apply只是參數(shù)不一樣。bind 綁定了之后創(chuàng)建一個新的綁定函數(shù)。改變了this。
-
new綁定
使用 new 來調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時,會自動執(zhí)行下面的操作。
- 創(chuàng)建(或者說構(gòu)造)一個全新的對象。
- 這個新對象會被執(zhí)行 [[ 原型 ]] 連接。
- 這個新對象會綁定到函數(shù)調(diào)用的 this。
- 如果函數(shù)沒有返回其他對象,那么 new 表達(dá)式中的函數(shù)調(diào)用會自動返回這個新對象。
-
-
箭頭函數(shù)中的this
在箭頭函數(shù)內(nèi)部,this 綁定不是 動態(tài)的,而是詞法的。什么時候創(chuàng)建一個作用域!頁面加載時候全局作用域 函數(shù)調(diào)用時候局部作用域。這個時候this已經(jīng)確定了 調(diào)用者一般決定著this的走向。
上面是基本概念,比較虛的。直接上代碼
代碼環(huán)境:

//直接在暴露在全局
```javascript
//直接在暴露在全局
const aa = () => {
console.log(this);
};
aa();
// 執(zhí)行出來之后就是 Window
這個很簡單。this指向Window嘛。至于為什么 因?yàn)檫@個aa是全局變量(是定義在最外面的變量),可以這樣理解,執(zhí)行時候它被全局環(huán)境所包含。所以就是windows。不過不掛在window全局對象上面哈。(這里理解一下 let const 和 var的掛全局對象的區(qū)別哈)。
// 繼續(xù)來一段:
const bb = {
aa: () => {
console.log(this);
},
b: function () {
this.aa();
}
};
bb.b();
// 這里還是輸出的Windows
// 繼續(xù)來一段:
const bb = {
aa: function() {
console.log(this);
},
b: function () {
this.aa();
}
};
bb.b();
// 這里輸出的bb的這個對象
非箭頭申明函數(shù)(普通函數(shù))只有函數(shù)執(zhí)行的時候才能確定this到底指向誰,實(shí)際上this的最終指向的是那個調(diào)用它的對象。
箭頭函數(shù)是在函數(shù)在定義時,this就繼承了定義函數(shù)的對象。 那么這個如何確定這個定義函數(shù)的this呢?還是從作用域。在當(dāng)前作用域內(nèi)this的指向。比如
const bb = {
aa: () => {
console.log(this);
},
b: function () {
this.aa();
}
};
bb = {} 是一個塊級作用域,訪問對象時候(個人感覺也會確定一個上下文。
然后加載一些活動記錄。this也在記錄里面,又因?yàn)閎b是全局變量。
所以就是this指向的就是Window)所以箭頭函數(shù)指向的就是Window。