「前端每日一问(37)」call、apply 和 bind 的区别是什么?

258 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

本题难度:⭐ ⭐

答:

函数中 this 的值可以使用 call、apply 和 bind 来显式改变。

apply 和 call 的功能完全一样,只是传参形式不一样,call 是传多个参数,apply 是只传参数集合。

bind 和 call、apply 的区别是,函数调用 call 和 apply 会直接调用,而调用 bind 是创建一个新的函数,必须手动去再调用一次,才会生效。

call

Function.prototype.call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

var lastName = 'xxx'
function fn () {
  console.log(this.lastName)
}

const obj = {
  lastName: 'lin'
}
fn()  // 输出 'xxx'
fn.call(obj) // 指定 this 为 obj,输出 'lin'

apply

Function.prototype.apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。

apply 和 call 的功能完全一样,只是传参形式不一样,call 是传多个参数,apply 是只传参数集合。

// 使用 call
function sum (x, y, z) {
  console.log(x + y + z)
}
sum.call(null, 1, 2, 3) // 6  第一个参数传 null,代表不改变 this 指向
// 使用 apply
function sum (x, y, z) {
  console.log(x + y + z)
}
sum.apply(null, [1, 2, 3]) // 输出 6,只是传参形式不同而已

bind

Function.prototype.bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

bind 和 call、apply 的区别是,函数调用 call 和 apply 会直接调用,而调用 bind 是创建一个新的函数,必须手动去再调用一次,才会生效。

var lastName = 'xxx'
function fn () {
  console.log(this.lastName)
}

const obj = {
  lastName: 'lin'
}
const fn1 = fn.bind(obj)
fn1() // 输出 'lin',必须手动再调用一次

bind 的参数传递方式和 call 相同,也是一个一个传递。

function sum (x, y, z) {
  console.log(x + y + z)
}
sum.bind(null, 1, 2, 3)() // 6

但是要注意,bind 的参数还支持像下面这样的方式传递:

function sum (i, j, k, l) {
  console.log(i + j + k + l)
}
sum.bind(null, 1)(2, 3, 4) // 10
sum.bind(null, 1, 2)(3, 4) // 10
sum.bind(null, 1, 2, 3)(4) // 10

这和函数式编程中的偏函数是类似的概念,详细可以了解这篇文章:

「前端每日一问(33)」闭包与柯里化函数、偏函数的关系?

结尾

阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

你也可以关注《前端每日一问》这个专栏,防止失联哦~

我是阿林,输出洞见技术,再会!

上一篇:

「前端每日一问(36)」闭包在类库封装中的应用

下一篇:

「前端每日一问(38)」列举一些call、apply、bind 的使用场景