JavaScript教程:箭头函数(lambda表达式)与this指向问题

说明

this的问题,见 JavaScript教程:this指向问题

使用 lambda 表达式可以解决该问题,在 lambda 表达式中,没有自己的 this,this永远指向定义函数的环境

解决

<script>
    let student = {
        age:20,
        grow:function(){
            console.log("grow函数中的 this :",this) // this表示当前对象
            setInterval( () => {
                console.log("setInterval()中的:",this) // this 是当前对象
                this.age ++
                console.log(this.age)
            },1000 )
        }
    }

    student.grow()

</script>

类中this指向问题

传统函数 this指向

<script>
    class Student{
        constructor(name,age){
            console.log("构造函数")
            this.name = name
            this.age = age
        }

        eat(food){
            console.log(this.name,"吃"+food,",this:",this)
            // 2秒后吃完
            setTimeout(function(){
                // 由于是匿名函数,所以此时this表示匿名函数的对象window,所以this.name 是空
                console.log(this.name,"吃完了,this:",this)
            },2000)
        }
    }

    const lilei = new Student('李雷',20)

    lilei.eat("大闸蟹")
</script>

缺点:

eat() 方法中的 this 指向是不同的

解决

在 eat() 方法中,将 this 赋值给一个 常量that,在 setTimeout() 中通过 that 访问当前对象

<script>
    class Student{
        constructor(name,age){
            console.log("构造函数")
            this.name = name
            this.age = age
        }

        eat(food){
            console.log(this.name,"吃"+food,",this:",this)
            // XXXXX关键代码XXXXX
            const that = this 
            // 2秒后吃完
            setTimeout(function(){
                // 由于是匿名函数,所以此时this表示匿名函数的对象window
                console.log(that.name,"吃完了,this:",this)
            },2000)
        }
    }

    const lilei = new Student('李雷',20)

    lilei.eat("大闸蟹")
</script>

箭头函数写法

箭头函数内部的 this ,继承上一层自定义函数的 this,若无上层自定义函数,则为 window

<script>
    class Student{
        constructor(name,age){
            console.log("构造函数")
            this.name = name
            this.age = age
        }

        eat(food){
            console.log(this.name,"吃"+food,",this:",this)
            // 2秒后吃完
            setTimeout(() => {
                // 由于是匿名函数,所以此时this表示外部eat()方法的当前对象
                console.log(this.name,"吃完了,this:",this)
            },2000)
        }
    }

    const lilei = new Student('李雷',20)

    lilei.eat("大闸蟹")
</script>


原文出处:/show_1IX3BvjYNkxu.html