Simple Call
簡易呼叫已經知道將 this 指向全域 window 的物件,下方程式碼為範例。
1 | var vm = "全域"; |
呼叫 home 這個函式並帶入參數內容,會得到一個全域物件跟帶入的參數值。
call
使用 call 的方法來呼叫 this 的話,可以改這樣寫。
1 | var vm = "全域"; |
呼叫 home 函式,並使用 call 的方法,將 family 物件取代 this,這個 this 就會指向 family,所以得到的值就會是 family 裡面的 vm。
apply
與 call 的方式相似,只是呼叫時帶入參數的格式不同,是用陣列表示。
1 | var vm = "全域"; |
call 跟 apply 的調用方法非常相似,且會立刻執行。
bind
別於上方兩個方法,bind 不會立刻執行,調用參數的方法與 call 相同。
1 | var vm = "全域"; |
使用 bind 的方法時,要先宣告一個變數,其值為呼叫函式並使用 bind,調用參數的方法與 call 相同,但並不會執行,而是要呼叫剛剛宣告的變數才會執行其函式,並把 this 替換掉。
容易被誤解的地方是呼叫的樣子跟 simple call 很像,但因為在使用 bind 方法時,已經決定呼叫的方法,所以不會跟 simpel call 的結果相同。
因為已經決定呼叫方式,所以在 otherHome 函式中加入參數,並不會改變其結果,但可以部分帶入參數,如下:
1 | var vm = "全域"; |
可見到如果 bind 方法只帶入一個參數 9
,第二個參數的位置會帶入函式中新帶入的第一個參數 1
,新帶入的第二個參數 2
,並不會被帶入。
進階觀念
前面 this 都是物件形態出現,這邊透過 call 的方法給予純值的話會變怎麼樣?
1 | var vm = "全域"; |
會看到得到的結果是:
this 變成一個建構式的樣子呈現 this,如果使用 typeof(this)
查看,會得到一個 object 的類型。
如果傳入文字,就會得到一個 string 的物件,那如果傳入 undefined
,結果則會指向 window 物件。
MDN 的說明:
若這個函數是在非嚴苛模式( non-strict mode ),
null
、undefined
將會被置換成全域變數,而原生型態的值將會被封裝
嚴格模式 use strict
因為 JavaScript 是弱型別的語言,規則上較為寬鬆,所以使用嚴格模式可以排除一些原本不會顯示的錯誤。
- 使用 ‘use strict’ 啟用嚴格模式。
- 對於沒支援嚴格模式的瀏覽器不影響。
- 可依照要執行嚴格模式的程式碼片段上方加入 ‘use strict’ 這個表達式。
- 可以排除一些不好的程式撰寫習慣。
- 不能使用未來被 ECMAScript 定義的關鍵字。
下方使用立即函式做為範例,並給予嚴格模式,來限制其執行環境,如下方程式碼:
1 | (function () { |
在立即函式中給一個變數與值,結果會跳錯,原因是在嚴格模式下不能直接讓變數賦予值,而是要先宣告一個變數再給予值。
1 | (function () { |
反之,如果把嚴格模式移除,就不會跳錯,但也不會執行。
嚴格模式在不同的瀏覽器所執行的結果會些許不同。
1 | function callStrict(param01, param02) { |
嚴格模式下可以看到 console 的結果就不會用建構式的方式呈現,就會按照原本的型別出現,如果 this 用 undefined
傳入也會得到 undefined
的值與型別。
1 | function callStrict(param01, param02) { |
如果在嚴格模式下使用 simple call 會變怎樣?
1 | function callStrict(param01, param02) { |
盡量不要使用 simple call 的 this 原因
有發現到就跟 undefined
是一樣的結果,所以得知,simple call 的 this 其實指向的就是 undefined
,所以盡量不要使用 simple call 的 this 的原因在此。