JavaScript教程:this指向问题

案例

定义对象,有 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()

原文出处:/show_1IX3iyFWMF0P.html