changed 5 years ago
Linked with GitHub

this

tags: javascriptadvancedconcept

this 在 javascript 通常用在物件導向或是事件監聽當中比較直觀而且確實應該用在那邊,如果用在其它地方可能就沒有什麼必要,而且還會造成易讀性差。

call 和 apply 的差別

callapply如果要傳this 的設定值的話,用法都是一樣的,在第一個參數輸入設定值即可:

function test() {
  console.log(this)
}

test.call(123)
test.apply(123)

但是如果要傳入引數到 function,我們看下面這個例子:

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

test.call(123, 1, 2, 3)
test.apply(123, [1, 2, 3])

call 的第二個引數(1)對應到 function 的第一個參數(a)、第三個引數(2)對應到 function 的第二個參數(b),以此類推;而apply 的第二個引數也是對應到 function 的參數,但是它必須傳入陣列才行,第一個陣列值(1)與 function 第一個參數(a)對應,以此類推。

在物件導向其他地方使用 this

this的值會被定義為如何呼叫它,使用什麼方式呼叫它,而不是取決於this在程式碼的位置與何時被定義。可以使用call(被呼叫的 function 前面的 object)來看比較容易,比如:

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

const a = obj.inner.test()
const b = obj.inner.test.call(obj.inner)

console.log( a ===  b) // true

上面的例子意思是可以把 obj.inner.test()obj.inner(也就是呼叫test() 的 object)放到 call 的參數當中來看,會和原本的結果一模一樣。因此使用 call() 一眼就可以看出 this 的值為何(這邊是 obj.inner)。

bind

bind方法可以綁定 object 的this 結果,也就是說不管怎麼 call object 結果都一樣,比如:

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

const bindTest = obj.test.bind('bind this')
bindTest()  // bind this
bindTest.call('123') // bind this

bind的結果會回傳一個新的 funciton 給bindTest,所以才會有怎麼 call 都會一樣的情形。

參考文章:

淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂

Select a repo