对于前端开发人员来说,搞清楚不同情况下的this指向,是一件非常头疼的事情。
经过收集资料,特此记录,以供后续复习使用
(1)普通函数中的this - 指向window
浏览器默认对象是window,如果一个函数体内,没有全局对象,则其中的this指向window
var b = 1
function fn(){
let a = 2
console.log(this.a)
console.log(this.b)
}
fn()
结果会输出 undefined 1
因为let是块级作用域,所以生效区域只有在函数体内,而this指向的是window。所以会输出undefined
而var定义的变量是全局变量,所以可以正常输出。
(2)构造函数中的this - 指向new的对象
function fn(){
console.log(this)
}
const Fn = new fn()
console.log(Fn)
结果会输出:fn{}
(3)箭头函数 - 指向调用上下文
箭头函数中没有this,指向其所在的上下文。
var a = 1
const Fn =(a,b)=>{
console.log(this.a,b)
}
Fn(2,3) //监听函数指向上一层作用域
结果会输出:1 3
(4)对象函数 - 指向这个对象
const obj= {
a:3,
objFun:function () {
console.log(this)
}
}
obj.objFun()
结果会输出:obj这个对象。
当然,还有一种可能,如果对象函数是箭头函数得话,那this也会指向父级作用域,比如:
var a = 1
const obj= {
a:3,
objFun:()=>{
console.log(this.a)
}
}
obj.objFun()//对象函数
结果会输出:1
注意:对象中的函数应该和对象属于同级,所以父级作用域也相同。
(5)数组中有函数 - 指向这个数组
function Fn() {
console.log(this)
}
var arr = [2,3,Fn ,4]
arr[2]()
结果会输出:这个数组
(6)window内置对象 - 指向window
setTimeout(()=>{
console.log(this)
},1000)
结果会输出window对象
(7)apply、call - 调用时指向第一个参数,没有传参时指向window
var a = 1 //关键是这里是否定义
function Fn() {
console.log(this)
}
Fn.apply(this.a)
如果a有定义,则this指向变为a。如果没有,则输出window
(8)Vue中的this指向问题
Vue中没有自定义new Vue的话默认this指向就是vueComponent。
官方的原话是:在Vue实例中,methods中如果用的是正常函数,那么它的this就指向Vue实例;
如果是箭头函数,this就指向window对象。
1、组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数,它们的this均是【VueComponent实例对象】
2、new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数中,它们的this均是【Vue实例对象】。
一、Vue普通方法中的this:
指向直接调用者。
比如在mounted里使用this,this指向调用它的Vue实例。
例如 obj.func ,那么func中的this就是obj,一般指的是实例。
二、vue所有生命周期中的钩子方法中的this:
比如在mounted里使用this,this指向调用它的Vue实例。
三、Vue 中回调函数中的 this:
若回调函数为 匿名函数,非严格模式下指向 window,严格模式下为 undefined。
若回调函数为 自定义方法,则 this 指向 Vue 实例。
若回调函数为 箭头函数,则 this 指向 Vue 实例。
四、Vue 中 addEventListener 中的 this
通常,事件监听函数中的 this 都指向绑定事件的那个元素, 但是在 Vue 中,监听函数中的 this 也指向 Vue 实例。
五、在data里定义Object类型的变量时的this
在data里定义Object类型的变量时,会发现Object中访问不到vue的this属性,例如:
export default {
data(){
return {
a: "123",
b: {
c: this.a
}
};
},
created() {
console.log("b: ", this.b.c); // undefined
}
}
想在b中访问this.a的数据,直接访问会返回undefined,因为这时c中的this指向的是b。
这种情况可以用到Object的get属性进行属性定义,例如:
export default {
data(){
return {
a: "123",
b: {
_target: () => this,
get target() {
return this._target();
},
get c() {
return this.target.a;
},
},
};
},
created() {
console.log("b: ", this.b.c); // 123
}
}
此处将this映射到了Object变量内部,然后通过get的形式定义属性并获取,这样就解决问题啦。