博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊一聊call、apply、bind的区别
阅读量:6222 次
发布时间:2019-06-21

本文共 2728 字,大约阅读时间需要 9 分钟。

我们都知道call apply bind都可以改变函数调用的this指向。那么它们三者有什么区别,什么时候该用哪个呢?

我们先直接通过代码实例来了解,后面再借助专业文档来解释。

举个?

// 有只猫叫小黑,小黑会吃鱼const cat = {    name: '小黑',    eatFish(...args) {        console.log('this指向=>', this);        console.log('...args', args);        console.log(this.name + '吃鱼');    },}// 有只狗叫大毛,大毛会吃骨头const dog = {    name: '大毛',    eatBone(...args) {        console.log('this指向=>', this);        console.log('...args', args);        console.log(this.name + '吃骨头');    },}console.log('=================== call =========================');// 有一天大毛想吃鱼了,可是它不知道怎么吃。怎么办?小黑说我吃的时候喂你吃cat.eatFish.call(dog, '汪汪汪', 'call')// 大毛为了表示感谢,决定下次吃骨头的时候也喂小黑吃dog.eatBone.call(cat, '喵喵喵', 'call')console.log('=================== apply =========================');cat.eatFish.apply(dog, ['汪汪汪', 'apply'])dog.eatBone.apply(cat, ['喵喵喵', 'apply'])console.log('=================== bind =========================');// 有一天他们觉得每次吃的时候再喂太麻烦了。干脆直接教对方怎么吃const test1 = cat.eatFish.bind(dog, '汪汪汪', 'bind')const test2 = dog.eatBone.bind(cat, '喵喵喵', 'bind')test1()test2()

clipboard.png

好了例子很简单但是基本的使用方法跟场景都涉及到了。

callapply的用法几乎一样,唯一的不同就是传递的参数不同,call只能一个参数一个参数的传入。

apply则只支持传入一个数组,哪怕是一个参数也要是数组形式。最终调用函数时候这个数组会拆成一个个参数分别传入。
至于bind方法,他是直接改变这个函数的this指向并且返回一个新的函数,之后再次调用这个函数的时候this都是指向bind绑定的第一个参数。bind传餐方式跟call方法一致。

由于apply函数传参的特殊性,我们又衍生出了一个黑魔法。

// 如果一个数组我们已知里面全都是数字,想要知道最大的那个数,由于Array没有max方法,Math对象上有// 我们可以根据apply传递参数的特性将这个数组当成参数传入// 最终Math.max函数调用的时候会将apply的数组里面的参数一个一个传入,恰好符合Math.max的参数传递方式// 这样变相的实现了数组的max方法。min方法也同理const arr = [1,2,3,4,5,6]const max = Math.max.apply(null, arr)console.log(max)    // 6

这里bind函数也有一个小技巧

// 如果你想将某个函数绑定新的`this`指向并且固定先传入几个变量可以在绑定的时候就传入,之后调用新函数传入的参数都会排在之后const obj = {}function test(...args) {console.log(args)}const newFn = test.bind(obj, '静态参数1', '静态参数2')newFn('动态参数3', '动态参数4')

clipboard.png

接着来看看MDN文档

call语法

  • fun.call(thisArg, arg1, arg2, ...)
  • thisArg: 在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
  • arg1, arg2, ... 指定的参数列表

apply语法

  • fun.apply(thisArg, [argsArray])
  • thisArg 在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
  • argsArray 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。

bind语法

  • fun.bind(thisArg[, arg1[, arg2[, ...]]])
  • thisArg 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当使用new 操作符调用绑定函数时,该参数无效。
  • arg1, arg2, ... 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

总结

  1. 当我们使用一个函数需要改变this指向的时候才会用到call`apply`bind
  2. 如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 ...)
  3. 如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 ...])
  4. 如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2...)

转载地址:http://gwgja.baihongyu.com/

你可能感兴趣的文章
手机/移动前端开发需要注意的20个要点
查看>>
高级单例模式:(利用自执行函数,可以通过return暴露私有变量,方法或者是通过window.方式暴露私有变量和方法)...
查看>>
iOS基于WebSocket的聊天机制(转)
查看>>
Nodejs文件上传
查看>>
关于v-for的一点小总结
查看>>
Nest.js 4.6.6 发布,更优雅的下一代 Node.js 开发框架
查看>>
CSS盒模型与BFC
查看>>
JS事件循环EventLoop初探
查看>>
Mac开发环境配置
查看>>
Telegram源码之安卓客户端配置
查看>>
Java精讲:生产者-消费者
查看>>
磊哥测评之数据库SaaS篇:腾讯云控制台、DMC和小程序
查看>>
JS中定时器线程理解
查看>>
记一次PMML文件的处理过程
查看>>
阿里云移动端播放器高级功能---视频下载
查看>>
后端_计算机网络
查看>>
关于大数问题的个人理解
查看>>
每日两道前端面试题 - 20190202
查看>>
用友云开发者中心助你上云系列之在线调试
查看>>
sequelize-cli 使用记录
查看>>