JavaScript 入門:this 是什麼、call/apply/bind 與 this 綁定規則解析

更新 發佈閱讀 11 分鐘

this 是一個關鍵字,在物件導向語言中表示對當前物件的引用。在 JavaScript 中,this 的值是動態的,它會指向某個物件,但具體指向哪一個物件取決於使用方法。

this 指向誰

在 JavaScript 中,this 是在函式被呼叫的時候決定的。也就是說,函式怎麼呼叫,決定了 this 指向誰。

第一種:普通函式直接呼叫 (預設綁定)

當函式不屬於任何一個物件,直接呼叫函式的話:

  • 非嚴格模式下,this 會指向全域物件
  • 嚴格模式下,this 則是 undefined
function sayHi(){
  console.log(this);
}
sayHi();

輸出結果

瀏覽器在非嚴格模式下,直接呼叫函式的 this 會屬於 window

瀏覽器在非嚴格模式下,直接呼叫函式的 this 會屬於 window

node.js 在非嚴格模式下,直接呼叫函式的 this 會屬於 global

node.js 在非嚴格模式下,直接呼叫函式的 this 會屬於 global

瀏覽器在嚴格模式下,直接呼叫函式的 this 會是 undefined

瀏覽器在嚴格模式下,直接呼叫函式的 this 會是 undefined

node.js 在嚴格模式下,直接呼叫函式的 this 會是 undefined

node.js 在嚴格模式下,直接呼叫函式的 this 會是 undefined

第二種:函式做為物件方法被呼叫 (隱式綁定)

這是前一篇文章的物件範例:

const person ={
name: "Elaine",
age: 18,
// 方法的縮寫
sayHi(){
console.log("Hi");
}
}

我們現在把 sayHi() 改寫成:

const person ={ 
name: "Elaine",
age: 18,
// 方法的縮寫
sayHi(){
console.log(`Hi, I'm ${this.name}.`);
}
}
person.sayHi(); // Hi, I'm Elaine.

在這個例子中,sayHi()person 這個物件呼叫,所以 this 會指向 person,因此可以取得 this.name = "Elaine"

第三種:使用 new 呼叫建構函式 ( new 綁定)

一樣是在前一篇文章有提到的內容:

function Person(name, age, height, weight){
  this.name = name;
  this.sayHi = function(){
    console.log("Hi");
  }
}
// 使用 new 運算子建立 instance
const person1 = new Person("Elaine");

使用 new 呼叫函式時,this 會被綁到新建立的物件實例上,這裡的 this 就會指向 person1

第四種:html DOM 事件中的事件處理機制

Html 事件中,this 會綁定接收事件的元素,以這個例子來說,this 就綁訂了這個 button 元素。

<html>
<head>
<title> Html this 測試</title>
</head>
<body>
<button id = "mybtn">點我</button>
</body>
<script>
const button = document.getElementById("mybtn");
button.addEventListener("click", function(){
console.log(this);
});
</script>
</html>

第五種:使用 call()apply()bind() 綁定 this (顯示綁定)

// 定義物件​
const person = {
greet: function(city, country){
console.log(`My name is ${this.firstName} ${this.lastName}. I'm from ${city}, ${country}.`);
}
}
// 定義函式
function age(){
console.log(`My age is ${this.age} years old.`);
}

const girl = {
firstName: "Elaine",
lastName: "Wang",
age: "23"
}
  • Call():用來指定 this 指向誰,並執行 function 或是其他物件的方法,返回值為函式執行結果。
// 使用 call 將 this 綁定到 girl 物件,並呼叫 person 物件的方法
person.greet.call(girl, "New York", "USA"); // My name is Elaine Wang. I'm from New York, USA.

// 使用 call 將 this 綁到 girl 物件,並呼叫函式 age
age.call(girl); // My age is 23 years old.
  • apply():用法與 call() 基本上相同,只差在 call() 將參數視為個別,而 apply() 將參數視為一個 array,返回值為函式執行結果。
// 使用 apply 將 this 綁定到 girl 物件,並呼叫 person 物件的方法
person.greet.apply(girl, ["New York", "USA"]); // My name is Elaine Wang. I'm from New York, USA.

// 使用 apply 將 this 綁到 girl 物件,並呼叫函式 age
age.apply(girl); // My age is 23 years old.

// 使用 apply 模擬其他方法,array 本身沒有 max 方法,可以用 apply 借用
​console.log(Math.max.apply(null, [1,2,3,4])); // 4
  • bind():用法與 call() 基本上相同,不一樣的是 bind 的返回值為新的函數,且這個綁定的 this 是永久綁定。
// 先新增另一個物件
const boy = {
  firstName: "Tom",
  lastName: "Lin",
  age: "25"
}

// 使用 bind 將 this 綁定到 boy 物件,並返回新的方法
const boy_greet = person.greet.bind(boy, "Tokyo", "Japan");
boy_greet(); // My name is Tom Lin. I'm from Tokyo, Japan.

const boy_age = age.bind(boy);
boy_age(); // My age is 25 years old.

setTimeout 與 setInterval 的 this 陷阱

我們在 person 物件中新增一個方法 sayMyName,並用 setTimeout 定時一秒。

const person = {
  name:"Elaine",
  greet: function(city, country){
    console.log(`My name is ${this.firstName} ${this.lastName}. I'm from ${city}, ${country}.`);
  },

  sayMyName(){
    setTimeout(function(){
      console.log(this.name);
    },1000);
  }
}

person.sayMyName(); // 輸出 undefined

為什麼這邊的 sayMyName 會輸出 undefined 呢?

前面說到「 this 是誰,取決於函式如何被呼叫」:

  1. person.sayMyName() 這行被呼叫時,this 指向呼叫他的物件,也就是 person。
  2. 但是 setTimeout(function(){...}, 1000) 裡面的 function 是 setTimeout 在一秒後以普通函式的形式呼叫的,所以會套用預設綁定的規則。

這個狀況在 setInterval 也是一樣的! 需要特別注意。那這種狀況要怎麼解決呢? 最推薦的做法是使用箭頭函式

箭頭函式在【JavaScript 入門:JS 的函式解析! 宣告式、表達式、箭頭函式】有介紹,忘了的朋友可以回去回顧一下~

箭頭函式與 this

在【JavaScript 入門:JS 的函式解析! 宣告式、表達式、箭頭函式】裡,其實已經提到過了 this,但是當時並沒有詳細的說明。

當時我們說到箭頭函式與其他函式的 this 規則不同,實際上,箭頭函式並沒有自己的 this,他的 this 會從外層作用域繼承。也就是說,箭頭函式在建立時就會捕捉當價作用域的 this,而不是在呼叫時才決定。

所以我們可以將上面 setTimeout 的範例改成:

const person = {
  name:"Elaine",
  greet: function(city, country){
    console.log(`My name is ${this.firstName} ${this.lastName}. I'm from ${city}, ${country}.`);
  },

  sayMyName(){
    setTimeout(()=>{
      console.log(this.name);
    },1000);
  }
}

person.sayMyName(); // 輸出 Elaine

這裡的 person.sayMyName 可以輸出 Elaine 是因為箭頭函式從外層繼承了 this


參考

  1. 解釋 JavaScript 中 this 的值?
  2. JavaScript this 关键字
  3. JavaScript 入門:物件 (Object )是什麼、要怎麼建立?
  4. JavaScript 入門:JS 的函式解析! 宣告式、表達式、箭頭函式


留言
avatar-img
Elaine 粼粼的林林總總
7會員
32內容數
不定期地分享程式/旅遊/學習/閱讀或各式各樣的文章,如果對我的分享有興趣,歡迎來找我玩~
2026/02/23
本文深入介紹 JavaScript 物件(Object)的核心概念,說明屬性與方法的定義方式、物件字面值與建構函式搭配 new 的差異。同時整理物件的存取方式(dot 與 bracket)、新增、修改、刪除屬性與遍歷技(Object.keys、values、entries)。
2026/02/23
本文深入介紹 JavaScript 物件(Object)的核心概念,說明屬性與方法的定義方式、物件字面值與建構函式搭配 new 的差異。同時整理物件的存取方式(dot 與 bracket)、新增、修改、刪除屬性與遍歷技(Object.keys、values、entries)。
2026/02/21
JavaScript 的動態型別特性容易引發隱性錯誤,本文解析 JavaScript 中常見的型別判斷方法,包括 typeof 、Array.isArray()、instanceof,以及 Object.prototype.toString.call(),並詳述它們的用法、例外情況與常見陷阱。
2026/02/21
JavaScript 的動態型別特性容易引發隱性錯誤,本文解析 JavaScript 中常見的型別判斷方法,包括 typeof 、Array.isArray()、instanceof,以及 Object.prototype.toString.call(),並詳述它們的用法、例外情況與常見陷阱。
2026/02/20
深入淺出講解 JavaScript 的單執行緒特性,以及事件循環 (Event Loop)、Call Stack、Web APIs、Task Queue、Microtask Queue 如何協同工作,實現非同步操作,讓 JavaScript 程式碼不會被長時間任務阻塞。
2026/02/20
深入淺出講解 JavaScript 的單執行緒特性,以及事件循環 (Event Loop)、Call Stack、Web APIs、Task Queue、Microtask Queue 如何協同工作,實現非同步操作,讓 JavaScript 程式碼不會被長時間任務阻塞。
看更多
你可能也想看
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
練習目標 這篇是我的前端練習記錄,透過 CodePen 製作一個小功能:「點一下按鈕,就讓整個畫面換個背景色」。 這個練習適合剛開始學習 HTML、CSS、JavaScript 的人,幫助理解: 按鈕怎麼綁定事件 JavaScript 怎麼控制畫面樣式 如何產生隨機顏色 練習畫面預覽
Thumbnail
練習目標 這篇是我的前端練習記錄,透過 CodePen 製作一個小功能:「點一下按鈕,就讓整個畫面換個背景色」。 這個練習適合剛開始學習 HTML、CSS、JavaScript 的人,幫助理解: 按鈕怎麼綁定事件 JavaScript 怎麼控制畫面樣式 如何產生隨機顏色 練習畫面預覽
Thumbnail
這篇文章深入淺出地解釋 JavaScript 中表達式 (expression) 與陳述式 (statement) 的差異,並以 React 中 JSX 的應用為例,說明為何大括號 {} 內只能放入表達式。文章以類比人類語言的句子結構來幫助理解,並提供相關參考資料連結。
Thumbnail
這篇文章深入淺出地解釋 JavaScript 中表達式 (expression) 與陳述式 (statement) 的差異,並以 React 中 JSX 的應用為例,說明為何大括號 {} 內只能放入表達式。文章以類比人類語言的句子結構來幫助理解,並提供相關參考資料連結。
Thumbnail
iFrame在微前端架構中的優缺點,分析了其對用戶體驗、SEO及性能的影響。 iFrame在嵌入小型UI元件、創建隔離環境等特定場景中仍具備相當的應用價值。
Thumbnail
iFrame在微前端架構中的優缺點,分析了其對用戶體驗、SEO及性能的影響。 iFrame在嵌入小型UI元件、創建隔離環境等特定場景中仍具備相當的應用價值。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
為什麼要登出使用者? 安全性:防止未經授權的人,在使用者暫離時使用系統,這在公用或共享電腦的環境中尤其重要。 資料保護:只要使用者處於登入狀態,就會暴露在個人資料被他人操縱或利用的風險中,因此登出閒置使用者對資安也很重要。 如何在 Vue 3 專案中實作此功能?
Thumbnail
為什麼要登出使用者? 安全性:防止未經授權的人,在使用者暫離時使用系統,這在公用或共享電腦的環境中尤其重要。 資料保護:只要使用者處於登入狀態,就會暴露在個人資料被他人操縱或利用的風險中,因此登出閒置使用者對資安也很重要。 如何在 Vue 3 專案中實作此功能?
Thumbnail
這一集用最新的Vite工具去創建初始檔案。Vite用於創建和構建Web應用程序,具有快速的啟動時間、即時熱更新、小型體積、支持多種框架和可擴展性等優點。
Thumbnail
這一集用最新的Vite工具去創建初始檔案。Vite用於創建和構建Web應用程序,具有快速的啟動時間、即時熱更新、小型體積、支持多種框架和可擴展性等優點。
Thumbnail
隨著科技發展迅速,軟體職缺需求大增長,有些朋友對IT產業有興趣並想成為一位軟體工程師,但不知道從哪裡下手,透過傳統學校、培訓班或自學等不同方法,有多種學習路徑可以選擇。此外,還提供了一些額外資源教學連結,方便讀者進一步提升相關技能。
Thumbnail
隨著科技發展迅速,軟體職缺需求大增長,有些朋友對IT產業有興趣並想成為一位軟體工程師,但不知道從哪裡下手,透過傳統學校、培訓班或自學等不同方法,有多種學習路徑可以選擇。此外,還提供了一些額外資源教學連結,方便讀者進一步提升相關技能。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News