JavaScript的this丢了怎么办?
JavaScript的this丢了怎么办?
bind方法
先来看一个常见的问题,以下示例中:
this.firstName
没有输出我们期望的 “John”,而显示了 undefined
!
let user={
firstName:"John",
sayHi(){
console.log(`Hello,${this.firstName}!`);
}
} ;
setTimeout(user.sayHi.bind(user),1000)
这是因为 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
就可以获取到正确的值了。
偏函数(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);
function mul(a,b,c){
return a*b+c
}
let double=mul.bind(null,2)
console.log(double(3,8))
分析
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)
为什么要创建偏函数?
首先:我们可以创建一个具有可读性高的名字(double
,triple
)的独立函数。我们可以使用它,并且不必每次都提供一个参数,因为参数是被绑定了的。
其次:当我们有一个非常通用的函数,并希望有一个通用型更低的该函数的变体时,偏函数会非常有用。
什么时候会用到偏函数?
当我们不想一遍又一遍地重复相同的参数时,偏函数非常有用。就像我们有一个 send(from, to)
函数,并且对于我们的任务来说,from
应该总是一样的,那么我们就可以搞一个偏函数并使用它。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现