JavaScript 的“This”關鍵字簡單介紹
2023-01-03由 skysevenqi 發表于 農業
whatsthis怎麼讀
每日分享最新,最流行的軟體開發知識與最新行業趨勢,希望大家能夠一鍵三連,多多支援,跪求關注,點贊,留言。
對於 JavaScript,
this
作為函式的一部分是一個棘手的關鍵字,因為由於被呼叫函式的隱式上下文,它的行為會有所不同。
作為物件的一部分,描述的簡短答案
this
是它是函式中的關鍵字,它使用包含函式的物件作為其值。
對於包含函式作為屬性的物件,這些函式是物件的方法,並且在執行時使用物件作為其執行上下文。
例如,假設我們有一個名為的物件
obje
,其中一個鍵的
obje
值為
num
“123”,而第二個鍵的值為
str
“abc”,第三個是一個被呼叫
func
的函式,其值是包含的函式
console。log(this)
。
const obje = {num: 123,str: ‘abc’,func: function(){console。log(this)}}
當您使用 呼叫
obje。func
時
()
,控制檯會完整記錄 的內容
obje
。
obje。func()//{ num: 123, str:‘abc’, func: [Function: func] }
透過提供的示例,一個簡單的描述
this
方法是它的值通常是被呼叫方法左側的包含物件。
在呼叫包含函式的全域性上下文中
this
, 的值
this
將是全域性物件,在瀏覽器中通常也稱為
window
。
console。log(this)Window {0: Window, window: Window, self: Window, document: document, name: ‘’, location: Location, …}
包含使用者可以訪問的
window
所有內容,如函式、變數和物件,這些內容既有可見的(如使用者宣告的),也有從幕後提供的(如內建的 JavaScript 方法)。
為了防止
this
使用全域性物件作為其值,我們可以
use strict
在函式中使用將其值更改為未定義。
function whatsThisHere(){ console。log(this)};whatsThisHere()// Object [global] {//global: [Circular *1],。。。
function whatsThisHere(){ ‘use strict’ console。log(this)};whatsThisHere()//undefined//undefined
常用的函式有 3 種方法
this
,它們分別
call
是
apply
和
bind
。
這些方法很有用,因為通常
this
在全域性上下文或不使用包含物件的上下文中呼叫函式 using 時, 的值
this
不再指向函式最初所在的物件,並且通常在函式執行時導致錯誤被執行。
const obje = {num: 123,str: ‘abc’,func: function(key, key2){return `Here is ${this[key]} and ${this[key2]}`};}}obje。func(‘num’, ‘str’)//‘Here is 123 and abc’const globFunc = obje。funcglobFunc(‘num’, ‘str’)//‘Here is undefined and undefined’
const obje = {num: 123,str: ‘abc’,nestFunc: { innerFunc: function(key, key2){return `Here is ${this[key]} and ${this[key2]}`} }};obje。nestFunc。innerFunc(‘num’,‘str’)//‘Here is undefined and undefined’
透過使用這三種方法,我們可以顯式設定 的值,
this
但它們也可以用於幫助抽象已經不屬於物件的函式。
function example(){return this}example。call(obje)//orexample。apply(obje)//{ num: 123, str: ‘abc’, func: [Function: func] }
call
可用於執行包含
this
引數引數的函式,允許將 的物件值
this
設定為第一個引數,
call
其餘的函式引數在第一個引數之後傳遞。
const obje = {num: 123,str: ‘abc’,};const globFunc = function(key, key2){return `Here is ${this[key]} and ${this[key2]}`};const globNum = ‘num’;const globStr = ‘str’;globFunc。call(obje, globNum, globStr)//orglobFunc。call(obje, ‘num’, ‘str’)//‘Here is 123 and abc’
apply
主要
call
區別在於設定後函式引數的引數
this
作為陣列提供,而不是單獨編寫單獨的引數。
const exArray = [‘num’,‘str’]globFunc。apply(obje, exArray)//or globFunc。apply(obje, [‘num’,‘str’])//‘Here is 123 and abc’
call
並且
apply
相似之處在於它們使用 set 引數立即執行函式,
this
並且附加引數作為函式的一部分傳遞。
該
bind
方法可用於設定物件
this
作為引數傳遞的上下文物件,但行為不同。
bind
用於
this
透過函式表示式宣告分配一個值,以建立一個單獨的函式,該函式具有一個“繫結”到函式的集合物件。
除了物件之外,無需新增其他引數來使用
bind
,除非您希望將引數永久附加到帶有物件的新函式。
的強度
bind
允許我們建立
this
繫結到
object
所選值的函式的副本,同時新增額外的引數,
call
並且
apply
將成為預設引數,以後不能更改。
與
call
and不同
apply
,
bind
不會立即執行。
const obje = {num: 123,str: ‘abc’,func: function(key){return `Here is ${this[key]}`};}}const bindFunc = obje。func。bind(obje);bindFunc(‘num’)//‘Here is 123’bindFunc(‘str’)//‘Here is abc’const bindFuncWithArg = obje。func。bind(obje, ‘num’)bindFuncWithArg(‘str’)//‘Here is 123’bindFuncWithArg()//‘Here is 123’
在我們在 Flatiron 的作業中,我們瞭解了“丟失上下文錯誤”,當
this
函式內部丟失其上下文時會發生這種錯誤,這可能是由於巢狀函式與被引用的物件不共享相同的上下文。
const obje = { fruitColors: { apple: “red”, banana: ‘yellow’, orange: “orange”, }, fruits: [‘apple’,‘banana’,‘orange’],};function whatColorFruit(fruit){ console。log(`The ${fruit} is ${this。fruitColors[fruit]}`)};whatColorFruit。call(obje, ‘apple’)//The apple is redfunction whatColorAll(){ const whatColor = function(fruit){ console。log(`The ${fruit} is ${this。fruitColors[fruit]}`)}; this。fruits。forEach(whatColor);};whatColorAll。call(obje)//TypeError: Cannot read properties of undefined (reading ‘apple’)
有不同的方法來處理丟失的上下文情況,補救這個錯誤的一種技術是使用
在要用於方法的巢狀函式上
bind
顯式設定上下文
。
this
forEach
function whatColorAll(){ const whatColor = function(fruit){ console。log(`The ${fruit} is ${this。fruitColors[fruit]}`)}。bind(this); this。fruits。forEach(whatColor);};whatColorAll。call(obje)//The apple is red//The banana is yellow//The orange is orange
或者
function whatColor(fruit){ console。log(`The ${fruit} is ${this。fruitColors[fruit]}`)};function whatColorAll(){ const bindColor = whatColor。bind(this) this。fruits。forEach(bindColor);};whatColorAll。call(obje)//The apple is red//The banana is yellow//The orange is orange
這裡我們使用設定
to
call
的值
,並
建立一個新的函式,其值
設定為
(取自
),這樣在放入
方法
時不會丟失的值。
this
obje
bind
this
obje
call
this
forEach
this
另一種方法是透過將值儲存到外部範圍中的變數
來手動設定上下文,並在巢狀函式中使用該變數,而不是
this
這樣我們就可以指向正在使用的物件而不會丟失
this
巢狀函式上下文中的值。
function whatColorAll(){ const self = this; const whatColor = function(fruit){ console。log(`The ${fruit} is ${self。fruitColors[fruit]}`)}; this。fruits。forEach(whatColor);};whatColorAll。call(obje)//The apple is red//The banana is yellow//The orange is orange
第三種簡單的解決方案是在巢狀函式中使用箭頭函式而不是函式表示式,因為箭頭函式使用父函式的上下文而不是建立另一個上下文。
這意味著我們不必
this
使用其他兩個選項手動設定 like 的值。
function whatColorAll(){ const whatColor = fruit => { console。log(`The ${fruit} is ${this。fruitColors[fruit]}`)}; this。fruits。forEach(whatColor);};whatColorAll。call(obje)//The apple is red//The banana is yellow//The orange is orange
結論
關鍵字
this
的行為方式有點奇怪,特別是因為它有可能根據函式呼叫的上下文而有所不同。
跟蹤其值的一種方法是簡單地 console。log 的值
this
以檢視正在使用的物件。
function whatsThisEach(){ const whatsThis = function(fruit){ console。log(this) }; this。fruits。forEach(whatsThis);};whatsThisEach。call(obje)// Object [global] {//global: [Circular *1],
在這裡,我們看到 value
this
是全域性物件,這有助於解釋為什麼如果我們沒有設定 value
this
或使用箭頭函式,它為什麼不能更早地工作。
function whatsThisEach(){ const whatsThis = fruit => { console。log(this) }; this。fruits。forEach(whatsThis);}; whatsThisEach。call(obje)//{fruitColors: { apple: ‘red’, banana: ‘yellow’, orange: ‘orange’}, fruits: [ ‘apple’, ‘banana’, ‘orange’ ]}//{fruitColors: { apple: ‘red’, banana: ‘yellow’, orange: ‘orange’ }, fruits: [ ‘apple’, ‘banana’, ‘orange’ ]}//{fruitColors: { apple: ‘red’, banana: ‘yellow’, orange: ‘orange’ }, fruits: [ ‘apple’, ‘banana’, ‘orange’ ]}
瞭解它的行為方式以及我們如何使用
call
apply
或
bind
幫助設定 的值
this
允許我們利用一種工具來幫助抽象函式,使它們更適用於在不同的執行上下文中處理不同的物件。
資源