深入JavaScript之call和apply方法

温浪

难兄难弟

我是js里的call方法,我和apply方法是难兄难弟。为什么这么说呢,因为很多前端小白看到咱俩就犯怵: "WTF!这是什么方法,根本看不懂啊!"然后去谷歌去百度,回来还是:"WTF!还是没懂!"。然后就把咱俩丢在一边不管了,心想:"哎,能不用就不用吧,反正也不见得用得着"。

借过来玩一玩

其实只要你认真的研究一下, 就会发现我和我哥们一点也不难。有些地方没有咱俩还真不行。要说咱俩有啥用,我管咱俩的功能叫借过来玩一玩。你看下面的例子啊:

let cat = {
    food: 'fish',
    eat: function() {
        console.log('I want to eat ' + this.food);
    },
   sleep: function(time) {
      console.log('I sleep' + time);
   }
}
let dog = {
    food: 'bone',
    playBall: function() {
        console.log('I am a doggy, I love playing ball');
    }
}
dog.playBall();    //I am a doggy, I love playing ball
cat.eat();    //I want to eat fish
cat.eat.call(dog);   //I want to eat bone

喵星人那里定义了eat方法,而汪星人里边只定义了playBall方法,懒惰的汪星人不想在自己内部再定义一个重复的eat方法,但是又想吃吃吃,那怎么办呢?
当然就是通过我call方法来找喵星人把eat方法借过来玩一玩啦。所以呢:
cat.eat.call(dog);的意思就是:喵哥!你的eat方法借dog玩一玩呗!你那个eat方法里的this现在指向了dog了啊!
这下你明白了为啥我的功能是借过来玩一玩了吧:
1.没有的方法我去别人那里借。
2.我可以改变被调用方法内部的this指向, this指向第一个参数。

除此之外,你可能会问了,假如我要调用的函数要接收参数,要怎么办呢?那么可以用到我call方法接收的第2,3,4...个参数了!

  cat.sleep.call(dog, 'all day'); //I sleep all day

我和我哥们apply的区别

我和我哥们apply区别很小很小,因为咱俩的主要功能都是一样的,都是借方法过来玩一玩外加改变this的指向,咱俩唯一的不同在于:
对于要借过来玩一玩的函数:

 function myFunction(arg1, arg2, arg3, arg4) {
    console.log(arg1);
    console.log(arg2);
    console.log(arg3);
    console.log(arg4);
}

我call的使用方法是myFunction.call(null, '1', '2', '3', '4')
而apply的使用方法是myFunction.apply(null, ['1', '2', '3', '4'])
看出来了么,apply这哥们有强迫症!他要把传进去的参数用数组包起来!而我就是一个一个往里传。你要是怕记混咱俩,你就这么记: 我是call,call就是打电话啊,打电话不得一个一个打吗,所以我的参数是一个个独立的。

这区别有啥用啊?

你可能又要问了:既然你俩区别这么小,而且看你上面的例子,既能用call又能用apply,那你俩这区别有啥用啊?
嘿嘿嘿,当然有用啦,看我给你举个栗子啊:

//这个函数熟悉吧?求传入参数的最大值
Math.max(1, 2, 3); //3

如果你是想求一个数组中的最大值, 咋办?把数组传入Math.max?当然不行,不信的话你可以试一下。这个时候我call方法就无能为力了,只能让apply帮你了:

let myArray = [1, 2, 3];
Math.max.apply(null, myArray);

ps: 也可以使用...运算符Math.max(...myArray);

最后

我们这对难兄难弟其实一点也不难啊!(╯﹏╰)

阅读 2.4k
1 篇内容引用

我回来啦!

943 声望
0 粉丝
0 条评论
推荐阅读
Python如何连接数据库
后端其实是JAVA项目,但是要用到python连接数据库(Mysql)做机器学习,所以先研究如何连接数据库.后面要研究JAVA如何调用Python脚本.

温浪阅读 908

嘿,vue中keep-alive有个「大坑」你可能还不知道
背景是这样的,我们使用vue2开发一个在线客服使用的IM应用,基本布局是左边是访客列表,右边是访客对话,为了让对话加载更友好,我们将对话的路由使用<keep-alive>缓存起来。但是如果将所有对话都缓存,未...

wuwhs3阅读 418

封面图
浏览器渲染原理(一文搞懂)
浏览器渲染原理前言浏览器的主要功能总结起来就是一句话:将用户输入的 URL 转变成可视化的图像。从 URL 到 DOM 树;从 DOM 树到可视化图像;这两个过程之间的关系并没有那么明确,我们可以统称这两个过程为页面...

风不识途1阅读 786

【验证码逆向专栏】安某客滑块逆向
声明本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!本文章未经许...

K哥爬虫1阅读 246

封面图
如何用JavaScripte和HTML 实现一整套的考试答题卡和成绩表
相信在学校的你都有这样的体验,临近考试,要疯狂的“背诵”否则成绩单就要挂零,因为答题卡全部涂抹都是错的。那么毕业多年的你,没有了考试,有没有一丝怀念涂答题卡的时候,有没有好奇这个答题卡到底如何制作,...

葡萄城技术团队1阅读 355

ES10 中 Object.fromEntries() 怎么用?
微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势,学习途径等等。本文 GitHub [链接] 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

前端小智2

我回来啦!

943 声望
63 粉丝
宣传栏