一个简单的例子让你很轻松地明白JavaScript中apply、call、bind三者的用法及区别

举报
零一01 发表于 2021/07/16 00:12:09 2021/07/16
【摘要】 JavaScript中apply、call、bind三者的用法及区别 引言正文一、apply、call、bind的共同用法二、 apply三、 call四、 bind五、其他应用场景六、总结 结束语 引言 这是我的第一篇前端面试题文章,也是用来帮助自己巩固复习知识, 在之后希望拿到自己满意的offer,这第一篇讲的就是一道常见的面试题,关于JavaS...

引言

这是我的第一篇前端面试题文章,也是用来帮助自己巩固复习知识, 在之后希望拿到自己满意的offer,这第一篇讲的就是一道常见的面试题,关于JavaScript中apply、call、bind三者的用法及区别。

  • 公众号:前端印象
  • 不定时有送书活动,记得关注~
  • 关注后回复对应文字领取:【面试题】、【前端必看电子书】、【数据结构与算法完整代码】、【前端技术交流群】

正文

如果有不想看过程的小伙伴可以直接跳到 总结

一、apply、call、bind的共同用法

先将一下特别概念性的,三者的共同用法就是可以改变函数的this指向,将函数绑定到上下文中。接下来看一个普通的应用场景:

let obj1 = { my_favorite : 'banana', add: function (fruit) { console.log('我喜欢的水果是' + fruit + ',但是我最爱的水果是' + this.my_favorite) }
}

let obj2 = {
	my_favorite: 'orange'
}

obj1.add('apple')
//输出结果为: 我喜欢的水果是apple,但是我最爱的水果是banana

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

可以看到最后一行代码我们调用了obj1中的add函数,并传入了一个参数apple。add函数中的 this 指的是他所在的对象obj1,所以this.my_favorite 就是banana, 但是我们如果想获得obj2中的my_favorite, 该怎么办呢?接下来看一下每个函数的用法吧~

二、 apply

语法:fun.apply(obj,[arry])

  • 第一个参数: 传入的是this需要指向的对象
  • 第二个参数: 传入的是一个数组,作为 fun 函数的参数
let obj1 = { my_favorite : 'banana', add: function (...fruit) {  //...fruit 表示的意思是可接收多个参数 console.log('我喜欢的水果是' + fruit + ',但是我最爱的水果是' + obj2.my_favorite) }
}

let obj2 = { my_favorite: 'orange'
}


obj1.add.apply(obj2, ['apple', 'Watermelon'])
//输出结果为:我喜欢的水果是apple,Watermelon,但是我最爱的水果是orange

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

obj1.add.apply(obj2, ['apple', 'Watermelon'])
这一行代码, 第一个参数将obj1中的add函数的 this 指向了obj2 , 第二个参数以数组形式传入多个参数,作为 obj1 中的 add 函数传入的参数, 所以最后能将 apple 和 watermelon 都输出。

三、 call

语法:fun.call(obj,[arg1, arg2, arg3...,argN]

  • 第一个参数: 传入的是this需要指向的对象
  • 其余参数: 除了第一个参数,其他的参数都是作为 fun 的传入参数

call 和 apply 唯一的区别就是在于给 fun 函数传入参数的形式不同, call是将多个参数逐个传入, apply 是 将多个参数放在一个数组中,一起传入

话不多说,直接来看看 call 的例子:

let obj1 = { my_favorite : 'banana', add: function (...fruit) { console.log('我喜欢的水果是' + fruit + ',但是我最爱的水果是' + obj2.my_favorite) }
}

let obj2 = { my_favorite: 'orange'
}


obj1.add.call(obj2, 'apple', 'Watermelon')
//输出结果为:我喜欢的水果是apple,Watermelon,但是我最爱的水果是orange

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

大家可以对比一下 call 和 apply 的区别到底在哪里

四、 bind

语法:fun.bind(obj)(arg)

  • bind的第一个参数:传入的是this需要指向的对象
  • 因为函数bind返回的是一个函数,即将 fun 的 this 指向 obj 后不进行自身调用, 我们需要自己进行一次调用, 所以要在函数bind后面再加一个小括号进行自身调用, 而小括号里则可以输出传给 fun 函数的参数, 输入的可以是数组形式的,也可以是逐个传入的。

简单看一下例子:

let obj1 = { my_favorite : 'banana', add: function (...fruit) { console.log('我喜欢的水果是' + fruit + ',但是我最爱的水果是' + obj2.my_favorite) }
}

let obj2 = { my_favorite: 'orange'
}


obj1.add.bind(obj2)('apple', 'Watermelon')
obj1.add.bind(obj2)(['apple', 'Watermelon'])
//输出结果为:我喜欢的水果是apple,Watermelon,但是我最爱的水果是orange
//输出结果为:我喜欢的水果是apple,Watermelon,但是我最爱的水果是orange

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

可以很清楚的看到, bind 有点类似 apply 和 call 的结合,只不过它返回的是一个函数,需要自己进行一下调用, 而传给 fun 函数的参数形式可以是像 apply 一样的数组形式, 也可以是像 call 一样的逐个传入的形式。

五、其他应用场景

  • 获取一个数组中的最大值或最小值
/* 普通情况,我们是这样获取数组中的最大值、最小值的 */

let max = Math.max(22, 33, 54, 88, 35, 44, 78, 80)
let min = Math.min(22, 33, 54, 88, 35, 44, 78, 80)
console.log(max, min)
//88  22

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

有没有感觉特别的麻烦,那接下来看看使用了这几个函数之后是什么样子的吧

/* 使用函数apply */
let arr = [22, 33, 54, 88, 35, 44, 78, 80]
let max = Math.max.apply(null, arr)
let min = Math.min.apply(null, arr)
console.log(max, min)
//88  22

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样看着是不是特别的简洁,因为我们不需要把arr 中的数组一个个传入进行比较,而是直接以数组形式传入就可以了。

六、总结

  1. apply、call、bind 三者都是可以改变函数的this指向的
  2. apply 和 call 都是改变函数this指向,并传入参数后立即调用执行该函数
  3. bind 是在改变函数this指向,并传入参数后返回一个新的函数,不会立即调用执行
  4. apply 传入的参数是数组形式的;call 传入的参数是按顺序的逐个传入并以逗号隔开; bind 传入的参数既可以是数组形式,也可以是按顺序逐个传入。

结束语

apply、call、bind三者的用法及区别是经常考到的一道面试题,希望对大家有所帮助。之后我还会每天更新一个前端面试题,来帮助大家以及我自己巩固知识点,喜欢的小伙伴可以点个关注, 希望你们都拿到自己满意的offer

文章来源: lpyexplore.blog.csdn.net,作者:「零一」,版权归原作者所有,如需转载,请联系作者。

原文链接:lpyexplore.blog.csdn.net/article/details/106249258

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。