🧙‍♂️闭包应用场景之--绑定上下文

74 阅读2分钟

前言

前面写过关于JavaScriptthis指向的基础文章,链接:juejin.cn/post/751796…

今天我们继续来讲讲闭包的应用场景之一:绑定上下文。

实例

来看看这个经典案例:

 const person = {
    name: "Alice",
    sayHello: function () {
        setTimeout(function () {
            console.log("Hello, " + this.name); 
        }, 1000);
    }
}
person.sayHello(); // 输出:

会输出什么呢?

Hello,Alice?

no!

会输出 Hello,undefined

这里涉及到this丢失问题,setTimeout定时器是个全局函数,所以执行的调用者是window,而它没有name属性,故为undefined

如何解决this丢失问题?

法一:that = this

const person = {
    name: "Alice",
    sayHello: function () {
        const that = this; // 保存this的引用
        setTimeout(function () {
            console.log("Hello, " + that.name);
        }, 1000);
    }
}
person.sayHello(); // 输出:Hello, Alice

这里在定时器前利用闭包的特性,用that保存了this,就可以正确引用name

法二:箭头函数

我们都知道箭头函数没有this,它会沿用词法作用域上层函数的this,我们可以借用它这个特性,来解决这个丢失问题。

const person = {
    name: "Alice",
    sayHello: function () {
        // this丢失
        setTimeout(()=> { // 改成箭头函数,他没有自己的this,会向上查找作用域链,找到this指向person对象
            console.log("Hello, " + this.name); 
        }, 1000);
    }
}
person.sayHello(); // 输出:Hello, Alice

这里的箭头函数的this来自沿用词法作用域上层函数(sayHello

法三:bind()

const person = {
    name: "Alice",
    sayHello: function () {
        // this丢失
        setTimeout(function () {
            console.log("Hello, " + this.name); // 这里的this指向window对象,因为setTimeout是一个全局函数
        }.bind(this), 1000);
    }
}
person.sayHello(); // 输出:Hello, Alice

函数是一等对象,当然可以调用bind()来改变this指向

.bind(this) 的作用是:创建一个新的函数,无论它在哪里被调用,它的 this 都永远指向当前绑定的对象。

在这里,外层函数中 this 是 person,所以 .bind(this) 把 this 绑定为了 person

结尾

闭包在面试中是个必考点,对它深入学习是很有必要的,一起加油吧!