JavaScript 程式執行原理:this


Posted by backas36 on 2021-08-16

this

剛剛提的那些物件導向的例子,我們使用到了很多次 this ,this 就是一個提供給物件導向來使用的,因為有了 this ,這樣 JS 才知道我們是指哪一個實例。

但是在物件導向以外也是可以使用 this,只是值可能會和在物件導向不一樣,例如在瀏覽器下 this 預設值就是 window,node.js 下就是 global,而且如果你是以嚴格模式 ( 'use strict' ) 下的話,this 就會變成 undefined。

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

call 與 apply

不過,如果在呼叫 function 時是使用 callapply 的話,this的值就會不一樣了,此時的 this 就會取決 callapply 的第一個參數是什麼。

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

學了 call ,之後我們就可以利用 call 來更了解 this:

'use strict'
const obj = {
    a: 666,
    inner: {
        test: function() {
            console.log(this)
        }
    }
}

obj.inner.test()    //{test: ƒ}

此時當你在執行 obj.inner.test() ,可以想像成像這樣 obj.inner.test.call(obj.inner)

如果我們新增一個變數放 obj.inner.test ,然後去呼叫呢?

'use strict'
const obj = {
    a: 666,
    inner: {
        test: function() {
            console.log(this)
        }
    }
}

const fn = obj.inner.test
fn()

在嚴格模式下,去呼叫 fn 的話,我們會得到 undefined,在寬鬆模式下,我們會得到 winodw。如果你用 call 去理解的話,就不會覺得那麼弔詭了,
當我們執行 fn() 就等於 fn.call(undefined) ,因為 this 取決於我們怎麼呼叫 function,如果是使用 call 或 apply 就是看第一個參數放什麼。

bind

bind 的行為跟 call 與 apply 很像,只是 call 與 apply,會直接呼叫 function,而 bind 是回傳一個 function。

'use strict'
const obj = {
    a: 666,
    inner: {
        test: function() {
            console.log(this)
        }
    }
}

const fn = obj.inner.test.bind('OMG')
fn()

this 會取決於 bind 的參數是什麼,所以此時就算使用 call 呼叫 fn fn.call('666') ,也是一樣會回傳 OMG。

arrow function 中的 this

arrow function 裡面的 this,跟剛剛說的 this 規則,是不一樣的,arrow function 裡面的 this,會取決於作用域。

'use strict'
const calcAge = function (birthYear) {

  console.log(2021- birthYear)   //32
  console.log(this) // undefined
}
calcAge(1989)

如果改成 arrow function 的話

'use strict'
    const calcAge = (birthYear) => {

      console.log(2021 - birthYear) //32
      console.log(this) //window
    }
    calcAge(1989)

為什麼會回傳 window 呢,這是因為在 arrow function 裡面的 this,其實就是上一層的 EC 裡面的 this,而上一層的 this,就是 window。

對於 this 和 JS 中的物件導向 有了一定的基礎概念後,現在我們可以來到最終章,再一次複習在 JS 中要怎麼實現物件導向的類別與實例 。


#js #this







Related Posts

MTR04 W2 D17 陣列練習題

MTR04 W2 D17 陣列練習題

位元運算與邏輯運算與電池燈泡的串聯並聯

位元運算與邏輯運算與電池燈泡的串聯並聯

使用Pagy製作Blog分頁(Ruby on Rails)

使用Pagy製作Blog分頁(Ruby on Rails)


Comments