聊一聊 Vue 中 watch 物件中的回呼函式為什么不能是箭頭函式
本文重點知識點速覽:
- Vue 中的 watch 物件中的回呼函式不能是箭頭函式,
- 箭頭函式中的 this 指向的是函式定義時所在的物件,普通函式中的 this 指向的是函式運行時所在的物件,
- 函式的 this 指向問題,
一起學習吧...
說起箭頭函式大家一定不陌生,箭頭函式是 ES6 中對函式的擴展,使用起來方便快捷,可能有些小伙伴對箭頭函式不是特別了解,所以在這里先舉個例子吧,
// 普通函式定義
function add(a, b) {
return a + b;
}
// 箭頭函式等價定義
const add = (a, b) => {
return a + b;
}
// 普通匿名函式
fucntion() {
console.log('hello');
}
// 箭頭函式等價定義
() => {
console.log('hello');
}
箭頭函式在定義回呼函式中使用的非常多,但是在 Vue 中的 watch 物件的回呼函式中就不能使用回呼函式,先看下面的例子:
代碼有一點長,簡單說明一下就不用看所有的代碼了,下面代碼實作的是實作監視資料 a 和 b 的變化,當其中一個改變時執行相應的回呼函式求a與b的和,重點在 23-30 行,
下面的代碼中 watch 中回呼函式是普通的函式,我們知道 對于普通函式,函式中的this指向函式運行時所在的物件,
所以,當我們在瀏覽器中改變a的值時(例如在瀏覽器的控制臺輸入 vm.a = 10),代碼 23 行列印出來的是一個 Vue 物件(即代碼 14行新創建出來的vm實體),因為此時 代碼 22 行的 function 函式運行在 vm 物件中,此時頁面會發生變化,由原來的 3 變為 12.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue中的watch</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
{{sum}}
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
a: 1,
b: 2,
sum: 3
},
watch: {
a: function() {
console.log(this);
this.sum = this.a + this.b;
},
b: function() {
this.sum = this.a + this.b;
}
}
})
</script>
</body>
</html>
我們再來看一下用箭頭函式當做 watch 的回呼函式的情況,把代碼21-29行換成如下的代碼即可:
watch: {
a: () => {
console.log(this);
this.sum = this.a + this.b;
},
b: () => {
this.sum = this.a + this.b;
}
}
當我們這時候再在瀏覽器的控制臺改變 a 的值時(比如 在控制臺輸入 vm.a = 10),會發現列印出來的是 window 物件,所以頁面的內容也不會發生變化,
JS 代碼分為 預決議階段和執行階段,在預決議階段遇到函式宣告會提前進行預決議,此時下面代碼中的箭頭函式會在全域定義,因為 var vm = new Vue({...}) 這句代碼在預決議階段還沒有被執行,當到了執行階段并且在控制臺改變 a 的值后,watch 中的下面代碼中的箭頭函式開始執行,此時的運行環境確實是新創建的 vm 物件,但是對于箭頭函式來說,箭頭函式中的 this 指向的是定義時的物件而不是函式運行時所在的物件,這一點與普通函式有很大的區別,
a: () => {
console.log(this);
this.sum = this.a + this.b;
}
如果對于 this 的指向問題如果還不是很清楚可以參考下面的兩篇博客:
-
圖文結合深入理解JS中的this值
-
深入理解this原理(JavaScript)
完
歡迎指正
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/165947.html
標籤:JavaScript
上一篇:MVVM決議
