物件導向裡面的 this

  • 物件導向裡面的 this 是欲存取的 instance
  • 哪一個 instance call function,this 就是哪一個 instance。

在非物件導向的情況下,this 會是什麼?

非嚴格模式下

  • node.js 上的 this 為 global
  • 瀏覽器上的 this 為 window

嚴格模式下皆為 undefined

'use strict'
function test() {
  console.log(this) // undefined
}
test()

在 addEventListener 裡的 this

實際操作到的就是 this

<button class="btn">我是按鈕</button>
<script>
  document
    .querySelector('.btn')
    .addEventListener('click', function() {
      alert(this) //[object HTMLButtonElement]
  })
</script>

傳什麼給 call,第一個參數值就是 this

'use strict'

function test() {
  console.log(this) // Number: 123
}

test.call(123)

call 跟 apply 的差異

  • call 可傳多個參數
  • apply 第二個參數必須是 array
'use strict'

function test(a, b, c) {
  console.log(this)
  console.log(a, b, c)
}

test.call(123, 1, 2, 3)
// Number: 123
// 1 2 3

test.apply(123, [1, 2, 3])
// Number: 123
// 1 2 3

用 call 來理解 this 是什麼

'use strict'

const obj = {
  a: 123,
  inner: {
    test: function() {
      console.log(this)
    }
  }
}

obj.inner.test() // { test: f }
obj.inner.test.call(obj.inner) // { test: f }

轉成 .call() 的形式

const func = obj.inner.test

func() => func.call(undefined)
obj.inner.test => obj.inner.test.call(obj.inner)
obj.test => obj.test.call(obj)

總結:不同 case 下,this 是什麼?

  1. 在非物件導向下
    • 嚴格模式 ('use strict'):this 為 undefined
    • 非嚴格模式:根據 runtime 決定;node.js 為 global,瀏覽器上為 window。
  2. 在物件導向下,this 就是自己的 instance
  3. 在 addEventListener 下,操作到的東西是 this。
  4. 在 obj 下,將其轉換為 .call() 的形式,this 是 .call() 內第一個參數。

.bind() 強制綁定 this

  • bind 直接綁定 this 是什麼,無法變動
  • p.s.:bind 是回傳一個 function,而 call、apply 是直接呼叫。
const obj = {
  a: 1,
  test: function() {
    console.log(this)
  }
}

const bindTest = obj.test.bind('555')
bindTest() // 555

arrow function 的 this

非 arrow function

class Test {
  run() {
    console.log('run this:', this)
    setTimeout(function() {
      console.log(this)
    }, 100)
  }
}
const t = new Test()
t.run()
// run this: Test {}
// window

arrow function

  • 會用定義好的 this。
  • this 跟怎麼呼叫沒有關係,跟哪邊定義有關係。
class Test {
  run() {
    console.log('run this:', this)
    setTimeout(() => {
      console.log(this)
    }, 100)
  }
}
const t = new Test()
t.run()
// run this: Test {}
// Test {}

參考資源


#程式導師實驗計畫第四期 #前端 #this







Related Posts

[JS101] 判斷式

[JS101] 判斷式

Day04 慣用寫法 (idioms)

Day04 慣用寫法 (idioms)

D5_寫作業

D5_寫作業


Comments