如何在回撥函式內部訪問正確的“this”?
在本教程中,我們將學習如何在回撥函式內部訪問正確的“this”。
“this”關鍵字
每個函式都包含一個稱為 this 的關鍵字,也稱為“上下文”,其值由函式的呼叫方式決定,而不是由其定義方式、時間或位置決定。與其他變數不同,它不受詞法作用域的影響。與其他語言相比,JavaScript 在使用函式的“this”關鍵字時略有不同。在嚴格模式和非嚴格模式之間,還有一些其他的變化。
函式的呼叫方式通常決定“this”的值(執行時繫結)。它在每次呼叫函式時都可能改變,並且在其執行期間不能透過賦值來改變。對於函式的呼叫方式,bind() 方法可以設定此值,因為箭頭函式沒有自己的“this”繫結(它保留封閉詞法上下文的“this”值)。
什麼是回撥函式?
從另一個函式接收引數的函式稱為回撥函式,通常在外部函式中稍後使用。外部函式接受回撥函式的術語稱為高階函式。
回撥函式擁有自己的一組方法和屬性,因為在 JavaScript 中函式是物件。“this”屬性在高階函式中執行時分配給回撥函式,完全取決於回撥函式的建立方式,而不是其定義位置、方式或時間。
透過檢查呼叫回撥函式的高階函式,我們可以確定回撥函式內的“this”值。封閉函式的實際定義可能包含區域性作用域屬性,這是回撥函式中 this 問題的主要原因。但是,由於回撥函式的上下文會根據其呼叫方式動態變化,因此在透過回撥函式內的“this”繫結訪問該屬性時,該屬性不存在。
現在我們將學習在回撥函式內部訪問正確的“this”的方法。
使用“self”模式
建立一個名為 self 的變數,併為其賦予在宣告函式的作用域中的 this 值,這是一個常見的模式。我們可以透過建立一個名為 self 的新變數(任何其他有效的變數名都可以)併為其賦予“this”的值來實現所需的行為。
示例
<html>
<body>
<h2> 'this' Inside a Callback using the <i> 'self' pattern </i> </h2>
<button onclick="myFunction()"> Click here </button>
<div id="root" style="
background-color: rgb(240, 248, 255);
border: 1px solid gray;
margin: 5px 0px;
padding: 10px;
">
Welcome to Tutorialspoint!
</div>
<script>
const root = document.getElementById('root')
function myFunction() {
this.variable = 'I am this variable'
const variable = 'I am a const variable'
const self = this
setTimeout(() => {
root.innerHTML = this.variable + '<br/>'
root.innerHTML += variable
}, 1000)
}
</script>
</body>
</html>
使用箭頭函式
ECMAScript 6 引入了 JavaScript 箭頭函式。它們沒有自己的繫結,並且是傳統函式表示式的更簡潔的替代方案。這確保瞭如果在箭頭函式內引用 this,則會在作用域中將其作為常規變數進行搜尋。
示例
<html>
<body>
<h2> 'this' Inside a Callback using the <i> arrow function </i> </h2>
<button onclick="myFunction('ABC')"> Click here </button>
<div id="root" style="
background-color: rgb(240, 248, 255);
border: 1px solid gray;
margin: 5px 0px;
padding: 10px;
">
Welcome to Tutorialspoint!
</div>
<script>
const root = document.getElementById('root')
function myFunction(name) {
this.name = name
let obj = {
run: function(callback) {
setTimeout(callback, 1000)
},
}
obj.run(() => {
root.innerHTML = this.name
})
}
</script>
</body>
</html>
使用另一個變數儲存“this”物件
物件連結到它,這通常是我們嘗試在回撥函式內部訪問 this 時真正想要訪問的內容。一種方法是在回撥函式作用域之前建立一個變數並存儲其值(儘管一些程式設計師可能不願意這樣做,因為它看起來很混亂)。
有些人稱之為 that 或 self,但只要術語清晰,名稱並不重要。此解決方法有效,因為該變數符合詞法作用域要求,因此在回撥函式內可用。您仍然可以訪問回撥函式的動態 this 繫結,這是此方法的額外好處。
示例
<html>
<body>
<h2>
'this' Inside a Callback using the
<i> another variable to store the 'this' object </i>
</h2>
<button onclick="myFunction('XYZ')"> Click here </button>
<div id="root" style="
background-color: rgb(240, 248, 255);
border: 1px solid gray;
margin: 5px 0px;
padding: 10px;
">
Welcome to Tutorialspoint!
</div>
<script>
const root = document.getElementById('root')
function myFunction(name) {
this.name = name
let that = this
let obj = {
run: function(callback) {
setTimeout(callback, 1000)
},
}
obj.run(function() {
root.innerHTML = this.name
})
}
</script>
</body>
</html>
顯式地將 this 繫結到物件
當我們定義回撥函式時,我們可以宣告我們希望 this 是什麼。我們可以使用 bind() 方法設定“this”值,並確保無論函式如何或在何處呼叫或傳遞,它都將保持不變。
bind() 方法在每個函式中都可用,並建立一個新的函式,其“this”屬性連線到給定的物件。返回的函式和原始函式之間的唯一區別是您可以完全控制“this”屬性指向的內容。
示例
<html>
<body>
<h2>
'this' Inside a Callback using
<i> explicitly binding this to an object </i>
</h2>
<button onclick="myFunction('Tutorialspoint')"> Click here </button>
<div id="root" style="
background-color: rgb(240, 248, 255);
border: 1px solid gray;
margin: 5px 0px;
padding: 10px;
">
Welcome to Tutorialspoint!
</div>
<script>
const root = document.getElementById('root')
function myFunction(name) {
this.name = name
let callbackFunction = function() {
root.innerHTML = this.name
}.bind(this)
let obj = {
run: function(callbackFunction) {
setTimeout(callbackFunction, 1000)
},
}
obj.run(callbackFunction)
}
</script>
</body>
</html>
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP