Vue:
不要在選項 property 或回調上使用箭頭函數,比如 created: () => console.log(this.a)
或 vm.$watch('a', newValue => this.myMethod())
。因為箭頭函數並沒有 this
,this
會作為變量一直向上級詞法作用域查找,直至找到為止,經常導致 Uncaught TypeError: Cannot read property of undefined
或 Uncaught TypeError: this.myMethod is not a function
之類的錯誤。
1.我們手寫復習一下js函數變量作用域的問題
//錯誤:c is not defined
var fs = function show() {
var c = 10;
}
console.log(c);
//結論:函數可以限制變量的作用域
//寫法1.
var c=new Date(); var obj = { age:c }
//寫法2.
var c=new Date();
var obj = {
age:c
}
//結論:這兩種寫法都是等價的,區別在於一個是匿名方法,一個非匿名方法
回到正題,先看下面的
案例1
var obj = {
say: ()=>{
console.log(this);
}
};
//此時this指向window
//我們按照上面的規則改寫,來找箭頭函數的作用域
var func = ()=>{
console.log(this);
};
var obj = {
say: func
};
//可以看到箭頭函數的作用域在windows,因為箭頭函數沒有作用域,js引擎向上查找箭頭函數內的this,當然是window了
案例2
var obj = {
say: function () {
setTimeout(()=>{
console.log(this);
}, 1000);
}
};
//改寫一下
var obj = {
say: function () {
var func = () => {
console.log(this);
};
setTimeout(func, 1000);
}
};
obj.say();
這個箭頭函數的this我們來找一下
首先切記箭頭函數沒有this,箭頭函數里面的this要向上查找
1.由於obj.say()可知say函數內的this執行obj
2.由於這個箭頭函數的作用域在say里,所以箭頭函數this就是say中的this就是obj
結論:
普通函數有調用者的概念誰調用this指代誰。
箭頭函數比較特殊沒有調用者,不存在this.箭頭函數()的概念,但是它內部可以有this,而內部的this由上下文決定