一文講解js中this指向問題(附程式碼)
之前的文章《中秋技巧篇:如何用CSS實現地球和月亮的公轉(收藏)》中,給大家介紹瞭如何用CSS實現地球和月亮的公轉。以下這篇文章給大家了解js中this指向問題,有一定的參考價值,有需要的朋友可以參考一下,希望對你們有所助。
JS中this指向問題
相信我,只要記住本文的7步口訣,就能徹底掌握JS 中的this
指向。
先念口訣:箭頭函數、new、bind、apply 和 call、歐比屆點(obj.)、直接呼叫、不在函數裡。
依照口訣的順序,只要滿足前面某個場景,就可以確定this
指向了。
接下來依照口訣順序對它們進行詳解,文中範例程式碼都運行在Chrome
的Console
控制台中。
文末有精心準備的練習題,用於檢驗學習成果,別忘了試試~
1. 箭頭函數
#箭頭函數排在第一個是因為它的this
不會被改變,所以只要目前函數是箭頭函數,那就不用再看其他規則了。
箭頭函數的this
是在建立它時外層this
的指向。這裡的重點有兩個:
1、創建箭頭函數時,就已經確定了它的this
#指向。
2、箭頭函數內的this
指向外層的this
。
所以要知道箭頭函數的this
就得先知道外層this
#的指向,需要繼續在外層應用七步驟口訣。
2. new
當使用 new 關鍵字呼叫函數時,函數中的 this 一定是 JS 建立的新物件。
讀者可能會有疑問,「如果使用new
關鍵呼叫箭頭函數,是不是箭頭函數的this
#就會被修改呢?」。
我們在控制台試一下。
func = () => {} new func() // throw error
從控制台中可以看出,箭頭函數不能當做建構函數,所以不能與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
不能是undefined
或null
。所以**在非嚴格模式下,透過上面七步驟口訣,如果得出this
#指向是undefined
或null
,那麼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()
非嚴格模式下執行結果為:
在严格模式下,执行同样的代码进行对比。记住要一次性将所有代码复制粘贴到控制台中,才能运行在严格模式下(因为第一行 "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()
严格模式下执行结果为:
七步口诀在严格模式下和非严格模式下都是完备的,只是在非严格模式下null
或undefined
会被转换为全局对象。所以我没有将这点列入口诀中。
做题复习
先背诵口诀再做题,“箭头函数、new
、bind
、apply
和call
、欧比届点(obj.
)、直接调用、不在函数里”。
1. 下面代码执行后,func.count 值为多少?
function func(num) { this.count++ } func.count = 0 func(1)
答案
func.count
值为 0。
按照口诀,func()
调用时属于第 6 类「直接调用」。在非严格模式下,this
指向全局对象。this
跟func
一点关系都没有,所以 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中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

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

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

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

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

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

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

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

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