1.常规函数中this
//第一种写法:
var vm = new Vue({
el:'app',
data:{
name:'',
list:[],
},
methods:{
handle :function(){
// this.list.push(this.name)
console.log(this) //es5的普通函数写法,这里指向的是vue实例
}
},
})
//第二种写法:es6对象属性函数的简写
var vm = new Vue({
el:'app',
data:{
name:'',
list:[],
},
methods:{
handle(){
// this.list.push(this.name)
console.log(this) //指向的是vue实例
}
},
})
小结:es5的普通函数,this指向是指向了调用者,这里的this会指向函数的“所有者”,就是当前Vue组件,大部分情况下,使用在这些地方:methods\computed属性\watched属性
2.箭头函数中this
- 箭头函数错用
```js
data() {
return {
text: 'This is a message',
};
},
methods: {
arrowFunction: () => {
console.log(this.text); // ERROR! this is undefined
}
}
//这里this并不指向函数的所有者,箭头函数使用所有的词法作用域,简单说就是vm实例所在的上下文(定义vm的父类),即window.*; 默认指向在定义它时所处的对象(宿主对象),而不是执行时的对象如果在Vue组件的箭头函数里访问this会报错,因为this不存在,
- 箭头函数巧用
//A.匿名函数
//用于临时创建、不需要在其他地方调用的函数,没有名字,直接绑定到哪个变量上,应用场景:使用fetch或axios获取数据、filter及map和reduce之类的函数式方法、Vue组件方法内部,代码举例如下:
//例1:
// 获取数据
fetch('/getSomeData').then((data) => {
this.data = data;
});
// 函数式方法
const array = [1, 2, 3, 4, 5];
const filtered = array.filter(number => number > 3);
const mapped = array.map(number => number * 2);
const reduced = array.reduce((prev, next) => prev + next);
// 我们是在常规函数内部使用箭头函数,这样常规函数就会将this设置为当前 Vue 组件实例,箭头函数就可以直接使用这个this了。
//例2:
data() {
return {
match: 'This is a message',
};
},
computed: {
filteredMessages(messages) {
console.log(this); // Vue 组件实例
const filteredMessages = messages.filter(
// 引用组件实例
(message) => message.includes(this.match)
);
return filteredMessages;
}
}
//这里之所以能访问到 this.match 是因为箭头函数的上下文跟filteredMessages方法的上下文是一致的,而filteredMessages是个常规函数而已,因此它的上下文就是组件实例。
//例3:
export default {
data() {
return {
dataFromServer: undefined,
};
},
methods: {
fetchData() {
fetch('/dataEndpoint')
.then(data => {
this.dataFromServer = data;
})
.catch(err => console.error(err));
}
}
}
//Promise 里的箭头函数可以正常访问this。
3、总结
常规函数和箭头函数的区别在于词法作用域。
先说作用域:也就是变量所处的程序范围。比如,window变量拥有全局作用域,任何位置都能访问它。
局部作用域:大部分变量被限制在函数、class或者模块内部,处于局部作用域。
再说词法:词法的意思是作用域是由代码书写方式决定的。有些编程语言是在程序运行时决定作用域的,这会导致很多困惑,因此大部分语言用的是词法作用域。箭头函数使用词法作用域,而常规函数不是。这里最棘手的部分是词法作用域如何影响函数中的this 。对于箭头函数,this 绑定到外部作用域的this 。常规函数绑定this 的方式有些奇怪,这就是为什么要引入箭头函数
// window 作用域
window.value = 'Bound to the window';
const object = {
// object 的作用域
value: 'Bound to the object',
arrowFunction: () => {
// 箭头函数使用 window 作用域的 `this`
console.log(this.value); // 'Bound to the window'
},
circleFunction() {
// 常规函数使用所属对象 object 作用域的 `this`
console.log(this.value); // 'Bound to the object'
}
};
可以通过call或者apply来执行函数,也可以用函数的bind 方法 :
func.call(obj, arg1, arg2);
func.apply(obj, args);
const boundFunction = unboundFunction.bind(this);