Javascript 中的 this

5 min readOct 23, 2022

Javascript this 一直都是面試問題的必考題之一,為了怕自己忘記還是先來記錄一下。

首先要知道的第一件事,在 javascript 中 this 的值是動態的,未指定的 this 都會指向全域。為什麼會這樣呢?先來看看 MDN 是如何定義 this:

In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called.

說明 this 的值是隨著被呼叫的方式而帶出不同的內容,換句話說,除了在未指定this指向全域外,this的內容還受函式的宣告方法影響,要搞清楚這裡就要介紹this的調用方式。

物件的方法調用 (As an object method)

我們稱在物件中新增的function為method,如果是呼叫物件中的method,method中的this會指向物件,這就是以物件方法調用,但是如果是直接呼叫物件中method,this則會指向window,以MDN對this的定義來說,this會因為function的呼叫方式而有所同,代表this的值其實是由被呼叫的方式來決定的而非以函式宣告的方式。

function callName() {
console.log(this.title)
}
var title = "I am object 1"
var object_2 = {
title: "I am object 2",
name: callName
}
object_2.name()//I am object 2
callName()//I am object 1

建構式的調用 (As a constructor)

講到this就一定要從物件導向開始談,在 javascript 中所有的資料都屬於object,缺少將所有資料聯繫起來的一種方式,所以就有了原型練(prototype chain)的出現。

new

在建構式下new會建立一個空物件,並且this會指向該物件,用以下範例解釋:

function DOG(name){this.name = namethis.species = '犬科'}var dogA = new DOG('大毛')console.log(dogA.name)//大毛

當我們使用new這個關鍵字的時候,過程中依序發生了這些事:
1. 建立一個空物件
2. 執行 DOG 函式
3. DOG 函式裡的 this 被指定成剛剛的空物件

call 與 apply 調用

apply和call的功能是改變 this 的值,套用後this就是就是指傳入的第一個參數。

function addFunc(a,b){
console.log(a + b)
}
function apply_add() {return addFunc.apply(this, arguments);}
apply_add(1,2); // 3
function call_add() {return addFunc.call(this, ...arguments);}
call_add(3,4); // 7

bind 調用

bind 跟 call、apply 不同的是,bind 綁定了 this 之後會建立一個新函式,不會回傳函式結果並且 this 是無法改變的。

function addFunc(...args){  let result = 0  args.map((arg) => result = result + arg)  console.log(this, result)}var add1 = addFunc.bind("total",1,2);var add_new = add1.bind("newt_value",2,3);add1(2,3)//total 8add_new(3,4)//total 15

總結

  • 在未指定this的狀況下,this都會指向全域。
  • this的值是以被呼叫的方式來決定。
  • call、apply、bind差異

call
語法:fn.call(this, arg1, arg2…, argn)
跟別的物件借用函式,必須逐項傳入

apply
語法:fn.apply(this, [arg1, arg2…, argn]
跟別的物件借用函式,接受傳入參數為陣列

bind
語法:fn.bind(this, arg1, arg2…, argn)
借用已建立的函式來創造新的函式,但將 `this` 綁到指定的物件上

參考資料

一次搞懂前端面試最愛問的 apply、bind、call
JavaScript 的 this 到底是誰?
談談 JavaScript 中的 “this” 和它的問題
this
What’s THIS in JavaScript ?
Javascript继承机制的设计思想
函數原型最實用的 3 個方法 — call、apply、bind

--

--

Penny Chang
Penny Chang

Written by Penny Chang

設計背景,熱愛探索多元創作領域。這裡分享我的設計靈感、學習筆記,以及生活中那些讓我成長(或翻車)的瞬間。更新佛系,看心情,有緣你就會看到。 [github: https://github.com/penny-3] [codepen: https://codepen.io/penny289]

No responses yet