JavaScript的this丢了怎么办?

484 阅读3分钟

「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战

前言

🍒 this相关

👉 JavaScript里this的绑定规则

👉 JavaScript里this的绑定优先级是怎么样的?

bind方法

先来看一个常见的问题,以下示例中:

this.firstName 没有输出我们期望的 “John”,而显示了 undefined

image-20211112211554462

这是因为 setTimeout 获取到了函数 user.sayHi,但它和对象分离开了,一旦方法被传递到与对象分开的某个地方 —— this 就丢失了。

在浏览器中, setTimeout 为函数调用设定了 this=window。所以对于 this.firstName,实时上变成了 window.firstName,很明显这是不存在的,所以结果变成了undefined


💡 那这要怎么办呢?

函数提供了一个内建方法 bind,它可以绑定 this

基本语法:let boundFunc = func.bind(context);

现在我们把上面的例子,加上bind方法在来试一下:

user.sayHi.bind(user)

可以看到输出结果正常,这句话的意思其实就是将当前的将 this 绑定到 user,这样this.firstName就可以获取到正确的值了。

image-20211112214141643


偏函数(Partial functions)

上面说到了绑定 this,事实上不仅可以绑定 this,还可以绑定参数(arguments)。

bind 的完整语法:let bound = func.bind(context, [arg1], [arg2], ...);

它允许将上下文绑定为 this,以及绑定函数的起始参数。

🎨示例:mul(a, b)是一个乘法函数

function mul(a, b) {
  return a * b;
}

现在我们想要在这个函数的基础上,创建一个double 函数,该怎么做呢?

你如果使用bind函数,很简单就可以实现了。

// 2倍函数
let double = mul.bind(null, 2);

image-20211112215049432

🍉分析

  • mul.bind(null, 2) 的调用创建了一个新函数 double
  • 它将调用传递到 mul,将 null 绑定为上下文
  • 2 绑定为第一个参数,即 a = 2
  • 而剩余参数(arguments)均被“原样”传递,即double(3),里面的3被原因传递给了b

从而非常简单的实现了,2倍函数,如果要实现3倍函数,直接传递3就可以了

let triple = mul.bind(null, 3);

注意:这里我们实际上没有用到 this。但是 bind 需要它,所以我们必须传入 null 之类的东西。

像上面这种,通过绑定先有函数的一些参数来创建一个新函数。叫做偏函数应用程序(partial function application)


💡 为什么要创建偏函数?

首先:我们可以创建一个具有可读性高的名字(doubletriple)的独立函数。我们可以使用它,并且不必每次都提供一个参数,因为参数是被绑定了的。

其次:当我们有一个非常通用的函数,并希望有一个通用型更低的该函数的变体时,偏函数会非常有用。


💡 什么时候会用到偏函数?

当我们不想一遍又一遍地重复相同的参数时,偏函数非常有用。就像我们有一个 send(from, to) 函数,并且对于我们的任务来说,from 应该总是一样的,那么我们就可以搞一个偏函数并使用它。

参考资料:

Function binding

MDN bind


🎨【点赞】【关注】不迷路,更多前端干货等你解锁

往期推荐

👉 前端生成二维码和条形码完整方案

👉 不能不知道的15 个JavaScript数组实用技巧

👉 给开发看的UI设计

👉 WebStorm提高工作效率的实用配置