如何理解JS中的call及apply

代码翱翔
• 阅读 862

这里是修真院前端小课堂,每篇分享文从

【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

八个方面深度解析前端知识/技能,本篇分享的是:

【如何理解JS中的call及apply】

 

1.背景介绍

在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。 JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。

2.知识剖析

call和apply的定义

1.call()方法调用具有给定this值的函数和单独提供的参数。说白了就是改变this的指向

2.apply()方法调用具有给定this值的函数,并作为数组(或类似数组的对象)提供。

3.常见问题

问题一:为什么要用call()和apply()方法?

问题二:call()和apply()两种方法的区别

4.解决方案

1.比如有段这样的函数:

function cat(){

}

cat.prototype={

food:"fish",

say: function(){

alert('I love '+this.food);

}

};

var blackCat = new cat;

blackCat.say();

var whiteDog = {food:'bone'};

blackCat.say.call(whiteDog);

我们有一个对象whiteDog = {food:”bone”},我们不想对它重新定义say方法,那么我们可以通过call或apply用blackCat的say方法:blackCat.say.call(whiteDog);

2.二者的区别

call与apply的区别 call, apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例,也就是每个方法都有call, apply属性.既然作为方法的属性,那它们的使用就当然是针对方法的了.这两个方法是容易混淆的,因为它们的作用一样,只是使用方式不同.

相同点:两个方法产生的作用是完全一样的

不同点:方法传递的参数不同

call()接受的是一个参数列表,而apply()接受一个参数数组。 func.call(this, arg1, arg2); func.apply(this, [arg1, arg2]) 其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。因此要说适用条件的话,当你的参数是明确知道数量时用 call 。 而不确定的时候用 apply,然后把参数 push 进数组传递进去。

举个小栗子来区别call和apply

获取数组中的最大值和最小值

var numbers = [5, 458 , 120 , -215 ];

var maxInNumbers = Math.max.apply(Math, numbers), //458

maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458

5.编码实战

见视频

6.扩展思考

还有哪些和call,apply类似的方法

bind() 方法

bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。 bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数,加上绑定函数运行时本身的参数,按照顺序作为原函数的参数来调用原函数。 也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。

7.参考文献
参考一:【优雅代码】深入浅出 妙用Javascript中apply、call、bind

参考二:js中bind、call、apply函数的用法

8.更多讨论

1.朱芳山:如果不用this还能不能使用call方法

分享人:做过demo,不用this,引用call等方法是无法借用函数

2.庄引:ES6中还有类似的替代方法吗?

龚家豪:createClass()

3.龚家豪:实际的应用场景

分享人:需要配合this方法使用

点赞
收藏
评论区
推荐文章
卡尔 卡尔
4年前
JS 手撕-经典面试题
引言首先出这篇文章,一方面是为了记录巩固我所学的知识,明白面试的高频考点。不鼓励大家背题的,初衷是希望总结的一些面试题能帮助你查漏补缺,温故知新。这些题并不是全部,如果你还想看得更多,可以访问,目前已经有552道大厂真题了,涵盖各类前端的真题,欢迎加入我们一起来讨论~函数call语法:fn.call(obj,...args)功
Dax Dax
3年前
JavaScript中call()、apply()、bind()的用法
call()apply()bind()都是用来更改this的指向的其中bind()返回的是一个函数,必须执行才行传参差异:call、bind、apply这三个函数的第一个参数都是this的指向对象,第二个参数差别就来了:call的参数是直接放进去的,第二第三第n个参数全都用逗号分隔,直接放到后面obj.myFun.call(db,'
Souleigh ✨ Souleigh ✨
4年前
每天学点 JS 编码规范(1):Types 和 References
每天学点JS编码规范(1):Types和References前端大全微信号FrontDev功能介绍分享Web前端相关的技术文章、工具资源、精选课程、热点资讯_前天_收录于话题(给前端大全加星标,提升前端技能)英文:AirBnB,翻译:Kak
小嫌 小嫌
3年前
bind()与call()和apply()之间的区别
具体内容以及示例可参见网站:需要记住的基本规则1."this"指代一个对象2."this"指的是调用它包含的函数的对象。3.在全局上下文中,“this”指的是窗口对象,或者如果使用“严格模式”则是未定义的。varcarregistrationNumber:"GA12345",brand:"Toyota",dis
Stella981 Stella981
3年前
JS中this和call
首先来了解一下JS中this的原理:要访问自己的属性就必须使用this.属性名1.this总是指向它的直接调用者:vara{user:'Artimis',fn:function(){console.log(this.user)}}a.fn()//Ar
Stella981 Stella981
3年前
Javascript 是如何体现继承的 ?
js继承的概念js里常用的如下两种继承方式:原型链继承(对象间的继承)类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念。所以,要想实现继承,可以用js的原型prototype机制或者用apply和call方法去实现在面向对象的语言中,我们使用类来创建一个自定义对象
Stella981 Stella981
3年前
JS 中的this指向问题和call、apply、bind的区别
this的指向问题一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向window。functiona(){console.log(this);//输出函数a中的this对象}functionb(){};varc{name:"call"}
Stella981 Stella981
3年前
JavaScript中call()与apply()有什么区别?
今天读《JavaScript权威指南》时发现其中有段代码用到了apply方法用于递归实现数组的展开。可是我不懂这个函数的用法,因此查了一下,将资料整理如下。Javascript的每个Function对象中有一个apply方法:function.apply(thisObj,argArray)还有一个类似功能的call方法:
代码翱翔
代码翱翔
Lv1
夜听胡笳折杨柳,教人意气忆长安。
文章
4
粉丝
0
获赞
0