標籤:不同 丟失 原理 container spl 對象 lis cal UNC
一、對this的產生原因分析和瞭解
第一:this
指的是函數運行時所在的環境。
第二:JavaScript 語言之所以有this
的設計,跟記憶體裡面的資料結構有關係(記憶體儲存詳細理解參考原文)。
總結如下:
對於普通對象的儲存:實際對象屬性的值就是值;
對於函數的儲存:實際函數屬性的值是函數的地址;(而函數本身,可理解為:它不屬於任何一個對象,相當於一個全域對象)
同時,函數,可以作為一個參數(值)被調用,被傳播。同時,在函數體內部,允許引用當前環境的其他變數(可以引用當前環境的其他變數。但當前環境是不確定的,所以會出現不同的值)
二、this綁定詳解
this
實際上是在函數被調用時發生的綁定,它指向什麼地方完全取決於函數在哪裡被調用。
2.1 預設綁定(綁定在全域範圍)
即在調用函數時,函數不帶任何修飾,也就是“光禿禿”的調用(即沒有任何修飾的調用),就會應用預設綁定規則, 預設綁定指向全域範圍。
注意:在 javascript 中,如果使用了strict 模式,則 this
不能綁定到全域對象。(不是很理解,不過先記錄下)
2.2 隱式綁定
當函數在調用時,如果函數有所謂的“落腳點”,即有內容物件(即調用時.
前面的對象)時,隱式綁定規則會把函數中的 this 綁定到這個內容物件。
function say() { console.log(this.name)}var name = "global"var obj = { name: "inside", say: say}var alias = obj.say // 設定一個簡寫 (1)alias() // 函數調用 輸出"global" (2)
注意:隱式綁定時丟失上下文問題。
這個可以結合函數的儲存理解為:obj.say
只是一個函數地址,不是函數本身。所以調用時,還是在當前全域環境下調用。
2.3 顯式綁定
javascript中提供三種顯式Binder 方法:apply
,call
,bind
。
apply |
call |
bind |
相同點 |
apply 和call 的用法基本相似 |
apply 和call 的用法基本相似 |
不同點 |
apply(obj,[arg1,arg2,arg3,...] 被調用函數的參數以數組的形式給出 |
call(obj,arg1,arg2,arg3,...) 被調用函數的參數依次給出 |
作用 |
apply , call 的作用就是給函數綁定一個執行內容,且是顯式綁定的。但傳入參數時會有所不同。 |
同左 |
注意:bind返回一個新函數,這個函數已經制定了執行內容(這表示執行內容在之後不可改變了),而返回這個新函數可以接受參數(即在綁定的執行內容中,以參數為入參執行函數)。
2.4 new 綁定
new 綁定:指通過 new
操作符調用建構函式時發生的 this
綁定。
注意:在 javascript 中並沒有其他語言那樣的類的概念。建構函式也僅僅是普通的函數而已,只不過建構函式的函數名以大寫字母開頭,也只不過它可以通過 new
操作符調用而已。
實際上:new 和 bind
應該很類似。只是一個在建立時執行,一個在執行過程中執行。(不過還是很不同的,見下文區別)
2.5 bind 和 new 的區別
不過還是有區別的:bind只能被函數調用。而new 返回的是一個對象。即new 之後,函數的執行內容就不可以被改變了,bind不行,顯示綁定的三種形式都不行。所以new 綁定 的優先順序最高。
2.6 四種綁定的優先順序和區別:
預設綁定 < 隱式綁定 < 顯式綁定 < new 綁定
注意:bind只能被函數調用。而new 返回的是一個對象。即new 之後,函數的執行內容就不可以被改變了,bind不行,顯示綁定的三種形式都不行。所以new 綁定 的優先順序最高。
三、參考
- JavaScript 的 this 原理 - 阮一峰的部落格 http://www.ruanyifeng.com/blog/2018/06/javascript-this.html
- JavaScript中this綁定詳解 - 想到什麼寫什麼 - SegmentFault 思否 1190000007101339
【JS】JS中對於this的理解