this 是 JavaScript 的一個關鍵字,也是讓新手困擾許久的主題,今天讓我們用更簡單、直接的方式來了解 this。
JavaScript 在任何地方都可以存取到 this,與其他程式語言慣用的 this 有了差異,造成了 JavaScript 的 this 難懂的原因。
理解 this 之前先告訴自己:
- 範圍鍊會向外部環境搜尋變數(所在的物件內找到答案),一但 this 脫離了物件,可能會導致參照全域環境,在這種情況下 this 會有個預設值,嚴格模式下的 this 預設值是 undefined,非嚴格模式下的 this 預設值是全域物件。
- this 與函式宣告位置無關,關鍵在於函式被呼叫的方式。
- this 指的是函式執行時,這個作用範圍(scope)的所有者(owner),你可以用 call、apply 與 bind 改變 this 指向的對象,簡而言之,this 就是你 call 一個函數時,所傳入的第一個參數。
- ES6 的箭頭函數沒有自己的 this,所以在箭頭函數裡看到 this ,就當作是外面函數的 this 即可。
接下來讓我們來點練習
練習一:變數參照全域環境
func(p1, p2) // 等同於 func.call(undefined, p1, p2)
練習二:變數參照物件
obj.child.method(p1, p2) // 等同於 obj.child.method.call(obj.child, p1, p2)
有點概念了嗎?那麼請問以下傳回的值:
function func() {
console.log(this);
}
func();
func( ) 等同於 func.call( ),嚴格模式下的 this 為 undefined,非嚴格模式下的 this 為 window 物件
var obj = {
foo: function(){
console.log(this);
}
}
obj.foo()
obj.foo( ) 等同於 obj.foo.call(obj),this 為 obj
var obj = {
foo: function(){
console.log(this);
}
}
var bar = obj.foo
obj.foo();
bar();
obj.foo( ) 等同於 obj.foo.call(obj),this 為 obj
bar( ) 等同於 bar.call( ),嚴格模式下的 this 為 undefined,非嚴格模式下的 this 為 window 物件
function fn() {
console.log(this);
}
var arr = [fn, fn2]
arr[0]();
arr[0]( ) 等同於 arr.0.call(arr),this 為 arr
var getGender = function() {
return this.gender;
}
var people1 = {
gender: ‘female’,
getGender: getGender
}
var people2 = {
gender: ‘male’,
getGender: getGender
}
console.log( people1.getGender() );
console.log( people2.getGender() );
console.log( people1.getGender( ) ) 等同於 people1.getGender().call(people1),this 為 female
console.log( people2.getGender( ) ) 等同於 people1.getGender().call(people2),this 為 male
感謝您的閱讀,我試著將生活與自己所學到的知識,以平易近人的方式傳達給正在努力進步的同好,甚至是領域之外卻有興趣的人。如果喜歡我的文章,歡迎贊助我,你的鼓勵也是我進步的動力。