目錄
JS中this指向問題
1. 箭頭函數
2. new
3. bind
多次bind 時只認第一次bind 的值
箭頭函數中this 不會被修改
bind 與new
4. apply 和call
bind 函數中this 不會被修改
5. 歐比屆點(obj.)
6. 直接呼叫
7. 不在函數裡
非嚴格模式
做题复习
2. 以下箭头函数中 this 指向谁呢?
首頁 web前端 js教程 一文講解js中this指向問題(附程式碼)

一文講解js中this指向問題(附程式碼)

Sep 17, 2021 am 10:16 AM
js

之前的文章《中秋技巧篇:如何用CSS實現地球和月亮的公轉(收藏)》中,給大家介紹瞭如何用CSS實現地球和月亮的公轉。以下這篇文章給大家了解js中this指向問題,有一定的參考價值,有需要的朋友可以參考一下,希望對你們有所助。

一文講解js中this指向問題(附程式碼)

JS中this指向問題

相信我,只要記住本文的7步口訣,就能徹底掌握JS 中的this指向。

先念口訣:箭頭函數、new、bind、apply 和 call、歐比屆點(obj.)、直接呼叫、不在函數裡。

依照口訣的順序,只要滿足前面某個場景,就可以確定this指向了。

接下來依照口訣順序對它們進行詳解,文中範例程式碼都運行在ChromeConsole控制台中。

文末有精心準備的練習題,用於檢驗學習成果,別忘了試試~

1. 箭頭函數

#箭頭函數排在第一個是因為它的this不會被改變,所以只要目前函數是箭頭函數,那就不用再看其他規則了。

箭頭函數的this是在建立它時外層this的指向。這裡的重點有兩個:

1、創建箭頭函數時,就已經確定了它的this#指向。

2、箭頭函數內的this指向外層的this

所以要知道箭頭函數的this就得先知道外層this#的指向,需要繼續在外層應用七步驟口訣。

2. new

當使用 new 關鍵字呼叫函數時,函數中的 this 一定是 JS 建立的新物件。

讀者可能會有疑問,「如果使用new關鍵呼叫箭頭函數,是不是箭頭函數的this#就會被修改呢?」。

我們在控制台試一下。

func = () => {} 
new func() // throw error
登入後複製

一文講解js中this指向問題(附程式碼)

從控制台中可以看出,箭頭函數不能當做建構函數,所以不能與new一起執行。

3. bind

bind 是指 Function.prototype.bind() 詳細位址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript /Reference/Global_Objects/Function/bind

多次bind 時只認第一次bind 的值

易錯點

function func() {
  console.log(this)
}

func.bind(1).bind(2)() // 1
登入後複製

箭頭函數中this 不會被修改

func = () => {
  // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
  console.log(this)
}

func.bind(1)() // Window,口诀 1 优先
登入後複製

bind 與new

易錯點

function func() {
  console.log(this, this.__proto__ === func.prototype)
}

boundFunc = func.bind(1)
new boundFunc() // Object true,口诀 2 优先
登入後複製

4. apply 和call

apply()call()的第一個參數都是this,差別在於透過apply呼叫時實參是放到陣列中的,而透過 call呼叫時實參是逗號分隔的。

箭頭函數中this 不會被修改

易錯點

func = () => {
  // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
  console.log(this)
}

func.apply(1) // Window,口诀 1 优先
登入後複製

bind 函數中this 不會被修改

易錯點

function func() {
  console.log(this)
}

boundFunc = func.bind(1)
boundFunc.apply(2) // 1,口诀 3 优先
登入後複製

5. 歐比屆點(obj.)

function func() {
  console.log(this.x)
}

obj = { x: 1 }
obj.func = func
obj.func() // 1
登入後複製

這裡就不用程式碼例證箭頭函數和bind 函數的優先權更高了,有興趣可自行嘗試吧。

6. 直接呼叫

在函數不滿足前面的場景,直接呼叫時,this將指向全域物件。在瀏覽器環境中全域物件是Window,在Node.js環境中是Global

先來個簡單的例子。

function func() {
  console.log(this)
}

func() // Window
登入後複製

來一個複雜的例子,外層的outerFunc就起個迷惑目的。

function outerFunc() {
  console.log(this) // { x: 1 }

  function func() {
    console.log(this) // Window
  }

  func()
}

outerFunc.bind({ x: 1 })()
登入後複製

7. 不在函數裡

不在函數中的場景,可分為瀏覽器的<script />標籤裡,或Node.js的模組檔案裡。

1、在<script />標籤裡,this指向Window

2、在Node.js的模組檔案裡,this指向Module的預設導出對象,也就是module. exports

非嚴格模式

嚴格模式是在ES5提出的。在ES5規範之前,也就是非嚴格模式下,this不能是undefinednull。所以**在非嚴格模式下,透過上面七步驟口訣,如果得出this#指向是undefinednull,那麼this會指向全域物件。 **在瀏覽器環境中全域物件是Window,在Node.js環境中是Global

例如下面的程式碼,在非嚴格模式下,this都指向全域物件。

function a() {
  console.log("function a:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

a()

a.bind(null)()

a.bind(undefined)()

a.bind().bind(2)()

a.apply()
登入後複製

非嚴格模式下執行結果為:

一文講解js中this指向問題(附程式碼)

在严格模式下,执行同样的代码进行对比。记住要一次性将所有代码复制粘贴到控制台中,才能运行在严格模式下(因为第一行 "use strict" 才会对后面的代码生效)。

"use strict"

function a() {
  console.log("function a:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

a()

a.bind(null)()

a.bind(undefined)()

a.bind().bind(2)()

a.apply()
登入後複製

严格模式下执行结果为:

一文講解js中this指向問題(附程式碼)

七步口诀在严格模式下和非严格模式下都是完备的,只是在非严格模式下nullundefined会被转换为全局对象。所以我没有将这点列入口诀中。

做题复习

先背诵口诀再做题,“箭头函数、newbindapplycall、欧比届点(obj.)、直接调用、不在函数里”。

1. 下面代码执行后,func.count 值为多少?

function func(num) {
  this.count++
}

func.count = 0
func(1)
登入後複製

答案

func.count值为 0。

按照口诀,func()调用时属于第 6 类「直接调用」。在非严格模式下,this指向全局对象。thisfunc 一点关系都没有,所以 func.count保持不变so easy

2. 以下箭头函数中 this 指向谁呢?

obj = {
  func() {
    const arrowFunc = () => {
      console.log(this._name)
    }

    return arrowFunc
  },

  _name: "obj",
}

obj.func()()

func = obj.func
func()()

obj.func.bind({ _name: "newObj" })()()

obj.func.bind()()()

obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })()
登入後複製

答案

// obj
// undefined
// newObj
// undefined
// bindObj
登入後複製

是不是很简单,你学废了吗?

推荐学习:JS视频教程

以上是一文講解js中this指向問題(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

建議:優秀JS開源人臉偵測辨識項目 建議:優秀JS開源人臉偵測辨識項目 Apr 03, 2024 am 11:55 AM

人臉偵測辨識技術已經是一個比較成熟且應用廣泛的技術。而目前最廣泛的網路應用語言非JS莫屬,在Web前端實現人臉偵測辨識相比後端的人臉辨識有優勢也有弱勢。優點包括減少網路互動、即時識別,大大縮短了使用者等待時間,提高了使用者體驗;弱勢是:受到模型大小限制,其中準確率也有限。如何在web端使用js實現人臉偵測呢?為了實現Web端人臉識別,需要熟悉相關的程式語言和技術,如JavaScript、HTML、CSS、WebRTC等。同時也需要掌握相關的電腦視覺和人工智慧技術。值得注意的是,由於Web端的計

如何使用JS和百度地圖實現地圖平移功能 如何使用JS和百度地圖實現地圖平移功能 Nov 21, 2023 am 10:00 AM

如何使用JS和百度地圖實現地圖平移功能百度地圖是一款廣泛使用的地圖服務平台,在Web開發中經常用於展示地理資訊、定位等功能。本文將介紹如何使用JS和百度地圖API實作地圖平移功能,並提供具體的程式碼範例。一、準備工作使用百度地圖API前,首先需要在百度地圖開放平台(http://lbsyun.baidu.com/)上申請一個開發者帳號,並建立一個應用程式。創建完成

股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟 股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟 Dec 17, 2023 pm 06:55 PM

股票分析必備工具:學習PHP和JS繪製蠟燭圖的步驟,需要具體程式碼範例隨著網路和科技的快速發展,股票交易已成為許多投資者的重要途徑之一。而股票分析是投資人決策的重要一環,其中蠟燭圖被廣泛應用於技術分析。學習如何使用PHP和JS繪製蠟燭圖將為投資者提供更多直觀的信息,幫助他們更好地做出決策。蠟燭圖是一種以蠟燭形狀來展示股票價格的技術圖表。它展示了股票價格的

如何使用PHP和JS創建股票蠟燭圖 如何使用PHP和JS創建股票蠟燭圖 Dec 17, 2023 am 08:08 AM

如何使用PHP和JS創建股票蠟燭圖股票蠟燭圖是股票市場中常見的技術分析圖形,透過繪製股票的開盤價、收盤價、最高價和最低價等數據,幫助投資者更直觀地了解股票的價格波動情形。本文將教你如何使用PHP和JS創建股票蠟燭圖,並附上具體的程式碼範例。一、準備工作在開始之前,我們需要準備以下環境:1.一台運行PHP的伺服器2.一個支援HTML5和Canvas的瀏覽器3

如何使用JS和百度地圖實現地圖點擊事件處理功能 如何使用JS和百度地圖實現地圖點擊事件處理功能 Nov 21, 2023 am 11:11 AM

如何使用JS和百度地圖實現地圖點擊事件處理功能概述:在網路開發中,經常需要使用地圖功能來展示地理位置和地理資訊。而地圖上的點擊事件處理是地圖功能中常用且重要的一環。本文將介紹如何使用JS和百度地圖API來實現地圖的點擊事件處理功能,並給出具體的程式碼範例。步驟:匯入百度地圖的API檔案首先,要在HTML檔案中匯入百度地圖API的文件,可以透過以下程式碼實現:

如何使用JS和百度地圖實現地圖熱力圖功能 如何使用JS和百度地圖實現地圖熱力圖功能 Nov 21, 2023 am 09:33 AM

如何使用JS和百度地圖實現地圖熱力圖功能簡介:隨著互聯網和行動裝置的快速發展,地圖成為了普遍的應用場景。而熱力圖作為一種視覺化的展示方式,能夠幫助我們更直觀地了解數據的分佈。本文將介紹如何使用JS和百度地圖API來實現地圖熱力圖的功能,並提供具體的程式碼範例。準備工作:在開始之前,你需要準備以下事項:一個百度開發者帳號,並建立一個應用,取得到對應的AP

PHP與JS開發技巧:掌握繪製股票蠟燭圖的方法 PHP與JS開發技巧:掌握繪製股票蠟燭圖的方法 Dec 18, 2023 pm 03:39 PM

隨著網路金融的快速發展,股票投資已經成為了越來越多人的選擇。而在股票交易中,蠟燭圖是常用的技術分析方法,它能夠顯示股票價格的變動趨勢,幫助投資人做出更精準的決策。本文將透過介紹PHP和JS的開發技巧,帶領讀者了解如何繪製股票蠟燭圖,並提供具體的程式碼範例。一、了解股票蠟燭圖在介紹如何繪製股票蠟燭圖之前,我們首先需要先了解什麼是蠟燭圖。蠟燭圖是由日本人

js和vue的關係 js和vue的關係 Mar 11, 2024 pm 05:21 PM

js和vue的關係:1、JS作為Web開發基石;2、Vue.js作為前端框架的崛起;3、JS與Vue的互補關係;4、JS與Vue的實踐應用。

See all articles