先来看一个例子,最近喜欢听Camila Cabello的Havana,就以她举例子吧
const havana = {
singer: 'Camila Cabello',
hobbies:['Sleeping','Songing','Reading'],
printHobbies: function(){
console.log(this);//"Camila Cabello",这里的this值是我们想要的.
this.hobbies.map(function(hobby){
console.log(this);//这里this的值是“window”,因为js中的this值是在运行的时候才绑定的,
console.log(`${this.singer} loves ${hobby}`);
})
}
}
havana.printHobbies();
这时候控制台的输出结果是:
loves Sleeping
loves Songing
loves Reading
singer不见了!
通过添加console.log(this);我们发现,在map里面的回调函数里的this指向了window,
这是因为:
1、js中的this值是在运行的时候才绑定的。
2、map里面的函数是map方法的回调函数,是一个独立的函数,它不作为对象的方法调用,如果不通过 call()、apply()、bind() 去改变 this 的指向的话,this就指向window,global,或undefined(严格模式).
我们通过在map上一行添加console.log(this);会发现这时候的this是我们希望得到的"Camila Cabello"。
我们把上面的例子改一下,
const havana = {
singer: 'Camila Cabello',
hobbies:['Sleeping','Songing','Reading'],
printHobbies: function(){
var that = this;//声明一个变量,给它赋值this
this.hobbies.map(function(hobby){
console.log(`${that.singer} loves ${hobby}`);
})
}
}
havana.printHobbies();
这里正确输出了:
Camila Cabello loves Sleeping
Camila Cabello loves Songing
Camila Cabello loves Reading
上面的例子,使用了传统的方法,在printHobbies的函数内部,添加了var that = this;然后使用that.singer调用singer,
现在我们使用es6箭头函数的写法看看:
const havana = {
singer: 'Camila Cabello',
hobbies:['Sleeping','Songing','Reading'],
printHobbies: function(){
this.hobbies.map(hobby=>{//改成箭头函数
console.log(`${this.singer} loves ${hobby}`);
})
}
}
havana.printHobbies();
这里也能正确输出了:
Camila Cabello loves Sleeping
Camila Cabello loves Songing
Camila Cabello loves Reading
那么,为什么箭头函数会达到这种效果呢?
箭头函数没有自己的this值,它的this值继承了它的父作用域。
箭头函数的this值是词法作用域,是在定义的时候,就被指定了的,以后也不会随着它调用方法的改变而改变。