已经介绍过JavaScript中this指向的原理,今天介绍一下this指向的几个复杂解析,和如何改变this的指向。
关于this的指向,有几个点需要注意:
举个?:
function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
const xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 29, 正常结果
getAge(); // NaN
this指向函数被调用的对象(执行环境)。
由于这是一个巨大的设计错误,ECMA规定,在strict模式下让函数的this指向undefined。
上面?在strict模式下调用getAge()
,会得到一个错误。这个决定只是让错误及时暴露出来,并没有解决this应该指向的正确位置。
有时因为编写闭包方式不同,也会导致this指向问题,而且不易被发现。
再来一个?:
const name = 'this window'
const obj = {
name : 'my object',
getName : function(){
function getNameFunc(){
return this.name
}
return getNameFunc()
}
}
obj.getName() //undefined
getNameFunc
在匿名函数中执行,匿名函数的执行环境具有全局性,this又指向window了!
修复第二个?:
const name = 'this window'
const obj = {
name : 'my object',
getName : function(){
const that = this; //that捕获this为对象obj
function getNameFunc(){
return that.name
}
return getNameFunc()
}
}
obj.getName() //my object
我们还可以调用函数本身的apply、call、bind来指定函数的this指向哪个对象。
apply接收两个参数,第一个参数是需要绑定的this变量,第二个参数是Array,表示函数本身的参数。
修复第一个?:
function getAge() {
const y = new Date().getFullYear();
return y - this.birth;
}
const xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 29, 正常结果
getAge.apply(xiaoming,[]); // 29,正常结果
call与apply类似,唯一的区别是:
apply()
把参数打包成Array传入,而call()
把参数按顺序传入。
函数的bind指定一个对象,将this绑定到这个对象上。
用bind修复第一个?:
function getAge() {
const y = new Date().getFullYear();
return y - this.birth;
}
const xiaoming = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); // 29, 正常结果
getAge.bind(xiaoming)() //29,正常结果
箭头函数解决了this指向混乱问题。
this对象的指向是可变的,但在箭头函数中它是固定的。
箭头函数有一个重要的特性:
函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象
解释一下底层原因:
this指针的固定化并不是箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this,正是因为它没有this,所以不能用作构造函数。
修复第二个?:
const name = 'this window'
const obj = {
name : 'my object',
getName : function(){
const getNameFunc = ()=> {
return this.name
}
return getNameFunc()
}
}
obj.getName() //my object
转载请标明来源:sherrybaby的博客