JavaScript 中 this 關鍵字的作用和如何改變其上下文

来源:https://www.cnblogs.com/yuzhihui/archive/2023/01/21/17063783.html
-Advertisement-
Play Games

JavaScript 中的 this 關鍵字引用了所在函數正在被調用時的對象。在不同的上下文中,this 的指向會發生變化。可以通過 call, apply, bind 方法來改變 this 的上下文。 ...


一、this 關鍵字的作用

JavaScript 中的 this 關鍵字引用了所在函數正在被調用時的對象。在不同的上下文中,this 的指向會發生變化。

在全局上下文中,this 指向全局對象(在瀏覽器中是 window 對象,在 Node.js 中是 global 對象)。

在函數中,this 指向調用該函數的對象。如果該函數是通過對象的方法調用的,那麼 this 指向該對象;如果是通過函數調用的,那麼 this 指向全局對象。

在箭頭函數中,this 繼承自父級作用域中的 this

在類的構造函數中,使用 new 關鍵字調用類時,this 指向新創建的對象。

例如:

class MyClass {
  constructor() {
    this.value = 42;
  }
}

let obj = new MyClass();
console.log(obj.value); // 42

類的實例方法中的 this 預設指向實例本身,類方法中的 this 預設指向類本身

例如:

class MyClass {
  value = 42;
  printValue() {
    console.log(this.value);
  }
  static printValue() {
    console.log(this.value);
  }
}

let obj = new MyClass();
obj.printValue(); // 42
MyClass.printValue(); // undefined

使用 Object.create 方法創建對象

使用 Object.create 方法創建是一種特殊的調用方式。在這種情況下,如果在對象的原型鏈上調用函數,則 this 指向該對象。

例如:

let baseObject = { value: 42 };
let obj = Object.create(baseObject);

function printValue() {
  console.log(this.value);
}

printValue.call(obj); // 42

這種情況下, obj 的原型鏈上有 value 屬性,所以調用 printValue() 方法時, this 指向 obj 對象。

在類中使用箭頭函數

類中使用箭頭函數定義的方法中的 this 指向是綁定的,它指向的是類的實例,而不是類本身。

例如:

class MyClass {
  value = 42;
  printValue = () => {
    console.log(this.value);
  }
}
let obj = new MyClass();
obj.printValue(); // 42

箭頭函數的 this 是定義時的 this,而不是調用時的 this。因此,在類中使用箭頭函數可以避免在方法中使用 bind 來綁定 this

在調用構造函數時,未使用 new 關鍵字

在這種情況下,this 指向全局對象。這種情況下不會創建新的對象,而是改變了全局對象的狀態。

例如:

class MyClass {
  constructor() {
    this.value = 42;
  }
}

let obj = MyClass(); // without new keyword
console.log(obj); // undefined
console.log(value); // 42

因此,在使用構造函數創建對象時,需要確保使用 new 關鍵字來調用構造函數,否則可能會導致意外的結果。

在使用構造函數時特別需要註意使用 new 關鍵字來調用。

在對象的方法中使用箭頭函數會導致 this 指向問題

例如:

let obj = {
  value: 42,
  printValue: () => {
    console.log(this.value);
  }
};
obj.printValue(); // undefined

這種情況下,在 obj 對象的 printValue 方法中使用了箭頭函數,而箭頭函數的 this 指向是定義時的 this,而不是調用時的 this。在這種情況下,因為箭頭函數的 this 指向是定義時的 this,所以 this.value 指向的是 undefined,而不是 obj 對象中的 value。

解決這種問題可以使用箭頭函數的父級作用域中的 this,或者使用普通函數來解決。

例如:

let obj = {
  value: 42,
  printValue: function(){
    console.log(this.value);
  }
};
obj.printValue(); // 42

或者

let obj = {
  value: 42,
  printValue: () => {
    console.log(obj.value);
  }
};
obj.printValue(); // 42

在對象的方法中使用箭頭函數會導致 this 指向問題,需要特別註意。可以使用箭頭函數的父級作用域中的 this 或者普通函數來解決。

總之,JavaScript 中的 this 關鍵字指向的上下文取決於函數的調用方式,需要根據不同的場景來選擇合適的方式來改變 this 的指向

二、如何改變 this 上下文

可以通過 call, apply, bind 方法來改變 this 的上下文。

callapply 方法允許您將函數的 this 指向指定的對象,並立即執行該函數。

call 方法的語法格式如下:

functionName.call(thisArg, arg1, arg2, ...);

apply 方法的語法格式如下:

functionName.apply(thisArg, [arg1, arg2, ...]);

bind 方法允許您將函數的 this 指向指定的對象,但不立即執行函數,而是返回一個新函數,可以在將來執行。

let newFunc = functionName.bind(thisArg, arg1, arg2, ...);

例如:

let obj = {value: 42};

function printValue() {
  console.log(this.value);
}

printValue.call(obj); // 42
printValue.apply(obj); // 42
let boundFunc = printValue.bind(obj);
boundFunc(); // 42

總之,通過使用 call, apply, bind 方法,可以改變函數中的 this 指向,從而在不同的上下文中使用同一個函數。

作者:yuzhihui
出處:http://www.cnblogs.com/yuzhihui/ 聲明:歡迎任何形式的轉載,但請務必註明出處!!!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 2023-01-20 一、springMVC中視圖及視圖解析器對象 1、視圖解析器對象(ViewResolver) (1)概述:SpringMVC中所有視圖解析器對象均實現ViewResolver介面 (2)作用:使用ViewResolver,將View從ModelAndView中解析出來 註:在s ...
  • 作者:京東物流 王北永 姚再毅 李振 1 背景 目前,ducc實現了實時近乎所有配置動態生效的場景,但是配置是否實時生效,不能直觀展示每個機器上jvm內對象對應的參數是否已變更為準確的值,大部分時候需要查看日誌確認是否生效。 2 技術依賴 1)Jsf:京東RPC框架,用作機器之間的通訊工具 2)re ...
  • 2023-01-20 一、SpringMVC處理響應數據 1、處理響應數據方式一 (1)語法:使用ModelAndView對象作為返回值類型,處理響應數據 (2)底層實現原理 ①數據共用到request域 ②跳轉路徑方式:轉發 (3)示例代碼 @RequestMapping("/testModelA ...
  • 常見的網路IO模型有4種:同步阻塞IO、同步非阻塞IO、IO多路復用以及非同步非阻塞IO。 RPC會採用IO多路復用的機制來管理網路通信。 ...
  • 寫在前面 在開發的過程中,大多數人都需要對代碼進行測試。目前對於c/c++項目,可以採用google的gtest框架,除此之外在github上搜索之後可以發現很多其他類似功能的項目。但把別人的輪子直接拿來用,終究比不過自己造一個同樣功能的輪子更有成就感。作為“linux環境編程”系列文章的第一篇,本 ...
  • 基於 LGT8F328P LQFP32 的 Arduino Mini EVB, 這個板型資料較少, 記錄一下開發環境和燒錄過程以及當中遇到的問題. ...
  • 介紹一些我常用的ssh工具 1、Xshell ​ Xshell應該是一款家喻戶曉的ssh連接工具,本人有幸也在很長一段時間都在使用Xshell,但是Xshell他是收費的!而且每次關閉後都會有一個提示框,我很不喜歡,而且Xshell的ftp或其他插件都是需要額外自行下載的,對於文件傳輸不太方便,但是 ...
  • JavaScript 中的作用域指的是變數和函數的可訪問範圍。 JavaScript 中,閉包是一個函數對象,它可以訪問定義該函數的作用域里的變數,即使函數已經返回。閉包的特點是,它可以在其相關環境不存在時保留變數。閉包可以被保存到變數中併在以後使用。它具有兩個特征,一是可以訪問外部函數的變數,二是... ...
一周排行
    -Advertisement-
    Play Games
  • 一:背景 1. 講故事 年前遇到了好幾例托管堆被損壞的案例,有些運氣好一些,從被破壞的托管堆記憶體現場能觀測出大概是什麼問題,但更多的情況下是無法做出準確判斷的,原因就在於生成的dump是第二現場,借用之前文章的一張圖,大家可以理解一下。 為了幫助更多受此問題困擾的朋友,這篇來整理一下如何 快狠準 的 ...
  • 前言 .NET6 開始,.NET Croe API 項目取消了 Startup.cs 文件,在 Program.cs 文件的 Main 函數中完成服務的註冊和中間件管道的管理。但當我們項目引入更多包的時候,Program.cs 文件也會看起來很臃腫。 而且,我們不只會有一個後端項目,為了方便快速創建 ...
  • 目錄 背景 get 與 post 的區別 所有介面都用 post 請求? 背景 最近在逛知乎的時候發現一個有趣的問題:公司規定所有介面都用 post 請求,這是為什麼? 看到這個問題的時候其實我也挺有感觸的,因為我也曾經這樣問過我自己。在上上一家公司的時候接到一個項目是從零開始搭建一個微服務,當時就 ...
  • *以下內容為本人的學習筆記,如需要轉載,請聲明原文鏈接 微信公眾號「englyf」https://mp.weixin.qq.com/s/2GFLTstDC7w6u3fTJxflNA 本文大概 1685 個字,閱讀需花 6 分鐘內容不多, 但也花了一些精力如要交流, 歡迎關註我然後評論區留言 謝謝你的 ...
  • 在新版本的pandas中,上述代碼會引起警告,建議改成SQLAlchemy connectable(engine/connection),後續代碼將引入這種升級的連接方式。 ...
  • 幾乎所有的高級編程語言都有自己的垃圾回收機制,開發者不需要關註記憶體的申請與釋放,Python 也不例外。Python 官方團隊的文章 https://devguide.python.org/internals/garbage-collector 詳細介紹了 Python 中的垃圾回收演算法,本文是這篇 ...
  • 如果您想查找高於或低於平均值的數字,可以不必計算該平均值,就能查看更高或更低的值。通過Java應用程式,可以自動突出顯示這些數字。除了快速突出顯示高於或低於平均值的值外,您還可以查看高於或低於的值的個數。現在讓我們看看如何在 Java應用程式中實現此操作。 引入jar包 導入方法1: 手動引入。將  ...
  • 第一種方式:使用{} firstDict = {"name": "wang yuan wai ", "age" : 25} 說明:{}為創建一個空的字典對象 第二種方式:使用fromkeys()方法 second_dict = dict.fromkeys(("name", "age")) #valu ...
  • 在golang中可以使用a := b這種方式將b賦值給a,只有當b能進行深拷貝時a與b才不會互相影響,否則就需要進行更為複雜的深拷貝。 下麵就是Go賦值操作的一個說明: Go語言中所有賦值操作都是值傳遞,如果結構中不含指針,則直接賦值就是深度拷貝;如果結構中含有指針(包括自定義指針,以及切片,map ...
  • 本文結合京東監控埋點場景,對解決樣板代碼的技術選型方案進行分析,給出最終解決方案後,結合理論和實踐進一步展開。通過關註文中的技術分析過程和技術場景,讀者可收穫一種樣板代碼思想過程和解決思路,並對Java編譯器底層有初步瞭解。 ...