JavaScript 中的 bind()、apply() 和 call():鲜为人知的差异

每个开发者都应该充分理解它们的工作原理,并能够辨别它们之间的微妙差异。

首先要知道,JavaScript 函数是“一等公民”。这意味着它们都是对象值——所有函数都是 Function 类的实例,拥有方法和属性:

d950777893c7c33b779b9a86a93a2ccb.png

因此,bind()apply()call() 是每个 JavaScript 函数都具备的三个基本方法。

bind()

你还记得 React 的早期痛苦时代吗?当时我们仍在使用类组件,并且事件处理程序通常是这样写的:

126817aad17d756ae868c15cbd25fcea.png

这只是 bind() 的众多应用之一——一个严重被低估的 JavaScript 方法。

没有 bind()sayName() 会一团糟——alert() 根本不会生效。

这是因为 React 在内部对这个方法做了一些处理,导致 this 的引用在方法内部完全被搞乱了。

最初,sayName 显示 alert 是没有问题的——就像在这个类中的另一个方法一样:

756308ae33aeb425f1084180df4722c0.png

026671edcc162abf3c896f0bfacde89b.png

但是,React 在后台对 greet 事件处理程序做了什么呢?它将其重新分配给另一个变量:

e9b8aa11f902b30ed57ac110c3676088.png

所以 this 发生了什么?它无法再被找到:

692e5a4634a7aba348e9c3e48f0dad3e.png

这时候 bind 派上了用场——它将 this 绑定到你选择的任意实例对象上:

const boundGreet = this.greet.bind(this);

所以我们将函数绑定到了对象——也就是 bind 的目标对象。

(我知道正确的说法是“bound”,但让我们像说“indexes”代替“indices”一样说“binded”吧)。

9f63c76e66acbb0e9dab3e5ba00f7943.png

bind 是不可变的——它返回绑定后的函数,而不会改变原始函数。

这让我们可以多次使用它:

342ae41b517e988bc82b70df62164ba4.png

对比 call()

callbind 之间只有一个很小的区别。

bind 创建一个绑定后的函数,可以多次使用。

call 呢?它会立即创建一个临时的绑定函数并调用它:

1fb01b543e6b4c82ea4401120bd9a780.png

所以 call() 基本上就是 bind() + 一次调用。

但是当函数有参数时怎么办?该如何处理呢?

完全没问题——只需将它们作为更多参数传递给 call

9ae2422f1bc1e1c551c2025d0e0fed9d.png

实际上,你也可以用 bind() 做同样的事情:

93337399707779eaa0c4f019d08c57a8.png

对比 apply()

一开始你可能会认为 apply()call() 完全一样:

ca7dccee128cc70bf2f9aae7bdd529b7.png

但是就像 bind()call() 之间有微妙的区别一样,apply()call() 之间也有一个细微的区别:参数的传递方式。

b3f4c14504b34d6a56904c998bdae94f.png

一个记忆技巧可以帮助你记住它们的区别:

  • call() 适用于用逗号分隔的参数

  • apply() 适用于数组

总结

  • bind()——绑定 this 并返回一个新的函数,可以重复使用。

  • call()——绑定并调用函数,使用逗号分隔的参数传递。

  • apply()——绑定并调用函数,使用数组传递参数。

这些函数方法是理解 JavaScript 函数和 this 关键字的基础,也是编写健壮代码的重要工具。

最后:

CSS技巧与案例详解

vue2与vue3技巧合集

VueUse源码解读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@大迁世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值