案例
定义对象,有 age 属性,有 grow() 长大方法,调用 grow() 方法时,让 age 属性加1
代码:
<script>
let student = {
age:20,
grow:function(){
console.log("grow() 中的this:",this)
// 通过this,访问 age 属性。没有this,表示访问全局变量或局部变量
this.age ++
console.log("长大一岁,今年:",this.age)
}
}
student.grow()
</script>
总结: grow() 方法中的 this 表示当前对象
this指向问题
在 grow() 方法中,调用 setTimeout() 间隔执行,延迟 1秒,让年龄增加1岁
代码:
function Student() {
this.age = 20,
this.grow = function(){
console.log("grow函数中的 this :",this) // this表示当前对象
setTimeout( function() {
// 由于 setInterval() 是 window 对象中的函数,所以 this 是 window对象
console.log("setTimeout()中的:",this)
this.age ++
console.log(this.age)
},1000 )
}
}
let lilei = new Student()
lilei.grow()
分析问题
匿名函数 传入 setTimeout(),由于 setTimeout() 是 window 对象下的函数,所以 匿名函数 中的 this 表示 window 对象
所以 this.age ++ 就变成了 window.age ++,所以不能通过 this 访问 age 属性
解决
解决方式一
使用 that
function Student() {
this.age = 20,
this.grow = function(){
let that = this // 在外部将 this 赋值给 that
console.log("grow函数中的 that :",that) // that 表示当前对象
setInterval( function() {
console.log("setInterval()中的:",that) // that 是 当前对象
that.age ++ // 这里调用that
console.log(that.age)
},1000 )
}
}
let lilei = new Student()
lilei.grow()
解决方式二
使用 箭头函数(lambda 表达式),箭头函数的 this 不是由调用方式决定的,而是由 它在代码中所处的位置(外层作用域) 决定的。它 “记住” 了定义时所在环境的 this
function Student() {
this.age = 20,
this.grow = function(){
console.log("grow函数中的 this :",this) // this表示当前对象
setInterval( () => {
console.log("setInterval()中的:",this) // this 是 window对象
this.age ++
console.log(this.age)
},1000 )
}
}
let lilei = new Student()
lilei.grow()