快速精通 JavaScript 的 “this”

閱讀時間約 4 分鐘
this 是 JavaScript 的一個關鍵字,也是讓新手困擾許久的主題,今天讓我們用更簡單、直接的方式來了解 this。
Photo made by me
JavaScript 在任何地方都可以存取到 this,與其他程式語言慣用的 this 有了差異,造成了 JavaScript 的 this 難懂的原因。

理解 this 之前先告訴自己:

  1. 範圍鍊會向外部環境搜尋變數(所在的物件內找到答案),一但 this 脫離了物件,可能會導致參照全域環境,在這種情況下 this 會有個預設值,嚴格模式下的 this 預設值是 undefined,非嚴格模式下的 this 預設值是全域物件。
  2. this 與函式宣告位置無關,關鍵在於函式被呼叫的方式。
  3. this 指的是函式執行時,這個作用範圍(scope)的所有者(owner),你可以用 call、apply 與 bind 改變 this 指向的對象,簡而言之,this 就是你 call 一個函數時,所傳入的第一個參數。
  4. ES6 的箭頭函數沒有自己的 this,所以在箭頭函數裡看到 this ,就當作是外面函數的 this 即可。

接下來讓我們來點練習

練習一:變數參照全域環境
func(p1, p2) // 等同於 func.call(undefined, p1, p2)
練習二:變數參照物件
obj.child.method(p1, p2) // 等同於 obj.child.method.call(obj.child, p1, p2)

有點概念了嗎?那麼請問以下傳回的值:

function func() {
  console.log(this);
}
func();
func( ) 等同於 func.call( ),嚴格模式下的 this 為 undefined,非嚴格模式下的 this 為 window 物件
var obj = {
    foo: function(){
      console.log(this);
  }
}
obj.foo()
obj.foo( ) 等同於 obj.foo.call(obj),this 為 obj
var obj = {
  foo: function(){
    console.log(this);
  }
}
var bar = obj.foo
obj.foo();
bar();
obj.foo( ) 等同於 obj.foo.call(obj),this 為 obj
bar( ) 等同於 bar.call( ),嚴格模式下的 this 為 undefined,非嚴格模式下的 this 為 window 物件
function fn() {
  console.log(this);
}
var arr = [fn, fn2]
arr[0]();
arr[0]( ) 等同於 arr.0.call(arr),this 為 arr
var getGender = function() {
  return this.gender;
}
var people1 = {
  gender: ‘female’,
  getGender: getGender
}
var people2 = {
  gender: ‘male’,
  getGender: getGender
}
console.log( people1.getGender() );
console.log( people2.getGender() );

console.log( people1.getGender( ) ) 等同於 people1.getGender().call(people1),this 為 female
console.log( people2.getGender( ) ) 等同於 people1.getGender().call(people2),this 為 male


感謝您的閱讀,我試著將生活與自己所學到的知識,以平易近人的方式傳達給正在努力進步的同好,甚至是領域之外卻有興趣的人。如果喜歡我的文章,歡迎贊助我,你的鼓勵也是我進步的動力。
為什麼會看到廣告
avatar-img
37會員
31內容數
短篇奇幻作品將不定期更新。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Ray C的沙龍 的其他內容
為了增進使用者體驗,前端愈來愈複雜,現在就讓我們一起搞懂技術名詞。
你可能已經看過 “ES6” 或 “JavaScript ES6” 一詞,並想知道它實際意味著什麼。別再想了,因為我們將深入研究 ES6 究竟是什麼,以及它與 JavaScript 的關係!
為了增進使用者體驗,前端愈來愈複雜,現在就讓我們一起搞懂技術名詞。
你可能已經看過 “ES6” 或 “JavaScript ES6” 一詞,並想知道它實際意味著什麼。別再想了,因為我們將深入研究 ES6 究竟是什麼,以及它與 JavaScript 的關係!
你可能也想看
Google News 追蹤
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
主要來講宣告函式跟箭頭函式 : 宣告函式(Function Declaration) 語法: function functionName(parameters) { return result; } 特點: 使用 function 關鍵字 函式名稱是必需的 存在函式
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹JavaScript中的物件導向編程。內容包括類別(Class)的定義和使用,建構子的作用,以及公開,私有,受保護(Protected)等不同訪問修飾符的概念。此外,還涵蓋了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型、反射等物件導向的主要觀念。
Thumbnail
這些章節的目的是為了介紹JavaScript中的各種數據類型,包括基礎類型和物件類型,以及如何將數據從一種類型轉換為另一種類型。此外,還介紹了如何創建自定義類型,以及如何使用JavaScript中的陣列、集合和字典。
※ ES6 變數宣告介紹: 在ES6中,推薦使用let和const取代原有的var來宣告變數。 ※ var的特點: 勢力範圍(scope)只有兩種:function、global(全域部分)。 勢力範圍(scope)指的是宣告變數的範圍,能夠被有效的使用的範圍。 可以在宣告變數之前就使用。
※ Object(物件) & Constructor Function(建構式函式) Object(物件)是什麼? 物件是一種「可以將資料、程式碼包含在其中」的資料結構。 Object(物件)的兩種創造方式: 匿名物件:直接使用"{}"。沒有特別的名字,直接從Object中繼承過來的一個物件
※ 函式基礎介紹: ※ JavaScript 特殊的函式特性: 函式可以當成值來傳遞 (可以放進變數或放進物件) 函式可以當成函式的參數 callback - 在特定事件中觸發函式 (非同步特性) ※ 函式的基本寫法: ※ 調用 (invoke) 函式: "調用" 意指呼叫或執行
Thumbnail
在之前的文章當中曾經提到過 JavaScript 中的物件有一個特別的機制:傳參考(Called by reference),如果正確性再高一點的話,則可以稱之為傳共享(Called by sharing)。
Thumbnail
這篇內容,將會講解什麼是腳本函式,以及與腳本函式相關的知識。包括腳本的簡介、使用函式(或全域變數)的注意事項、定義全域變數、定義函式、什麼是宣告、局部變數的應用。
主要來講宣告函式跟箭頭函式 : 宣告函式(Function Declaration) 語法: function functionName(parameters) { return result; } 特點: 使用 function 關鍵字 函式名稱是必需的 存在函式
就是指變數可以被訪問和使用的範圍,來說一下var、let和const的作用域差異。 var :function example() { console.log(x); // 輸出: undefined 因為變量提升造成的 var x = 5; } 函數作用域或全域作用域 可以重複宣告
Thumbnail
本章節旨在介紹TypeScript中的函數,包括其基本結構、如何呼叫函數、函數的參數以及函數的返回值等相關概念。通過本章節,讀者可以學習到如何在TypeScript中使用不同的方式來定義函數,如函數聲明、函數表達式、箭頭函數和匿名函數等。
Thumbnail
本章節旨在介紹JavaScript中的物件導向編程。內容包括類別(Class)的定義和使用,建構子的作用,以及公開,私有,受保護(Protected)等不同訪問修飾符的概念。此外,還涵蓋了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型、反射等物件導向的主要觀念。
Thumbnail
這些章節的目的是為了介紹JavaScript中的各種數據類型,包括基礎類型和物件類型,以及如何將數據從一種類型轉換為另一種類型。此外,還介紹了如何創建自定義類型,以及如何使用JavaScript中的陣列、集合和字典。
※ ES6 變數宣告介紹: 在ES6中,推薦使用let和const取代原有的var來宣告變數。 ※ var的特點: 勢力範圍(scope)只有兩種:function、global(全域部分)。 勢力範圍(scope)指的是宣告變數的範圍,能夠被有效的使用的範圍。 可以在宣告變數之前就使用。
※ Object(物件) & Constructor Function(建構式函式) Object(物件)是什麼? 物件是一種「可以將資料、程式碼包含在其中」的資料結構。 Object(物件)的兩種創造方式: 匿名物件:直接使用"{}"。沒有特別的名字,直接從Object中繼承過來的一個物件
※ 函式基礎介紹: ※ JavaScript 特殊的函式特性: 函式可以當成值來傳遞 (可以放進變數或放進物件) 函式可以當成函式的參數 callback - 在特定事件中觸發函式 (非同步特性) ※ 函式的基本寫法: ※ 調用 (invoke) 函式: "調用" 意指呼叫或執行
Thumbnail
在之前的文章當中曾經提到過 JavaScript 中的物件有一個特別的機制:傳參考(Called by reference),如果正確性再高一點的話,則可以稱之為傳共享(Called by sharing)。