JavaScript中apply与call的用法详解及区别
本文详细解析JavaScript中apply和call函数的核心机制。重点阐述两者在替换this指向上的共性,以及参数传递方式的差异:apply接收数组或类数组对象,而call接收独立参数列表。通过代码示例说明如何利用它们结合Math函数求最值、合并数组,并澄清执行顺序与返回值对this的影响。
JavaScript中apply与call的用法详解及区别
前言
针对call与apply,既往认知常存偏差,本文旨在通过笔记梳理实现彻底掌握,并协助学习者攻克这一难点。
apply函数定义与理解
一、apply函数定义与理解,先从apply函数出发
依据MDN文档,apply的定义如下:
“apply()方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。”
个人理解:若apply前存在含this的对象A,且参数中包含含this的对象B,则A.apply(B)意指A代码执行调用了B。B代码照常执行,其结果作为apply的参数,随后apply将该结果所代表的this替换掉A原本的this,进而执行A代码。
例如:
var aa = {
_name:111,
_age:222,
_f:function(){
console.log(this)
console.log(this._name)
}
}
var cc = {
_name:0,
_age:0,
_f:function(){
console.log(this)
console.log(this._name)
}
}
cc._f.apply(aa)//此时aa表示的this就是aa本身
cc._f.apply(aa._f)//此时aa._f表示的this就是aa._f本身
/**
* 此时aa._f()表示的this,就是执行后的结果本身。aa._f()执行后,没有返回值,所以应该是undefined,而undefined作为call和apply的参数时,call和apply前面的方法 cc._f 的this会替换成全局对象window。
* 参考MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply 的参数说明
*/
cc._f.apply(aa._f())
执行结果:
1.参数为aa
这两行的打印均来自cc._f方法内的两句console。当参数为aa时,属于初始化阶段,此时aa._f方法并未执行。
2.参数为aa.f
这两行的打印均来自cc._f方法内的两句console。当参数为aa.f时,同样属于初始化或作为不执行的函数参数传入,即aa._f方法未执行。
3.参数为aa.f()
这四行的打印中,前两行源自aa._f()方法执行后的结果;后两行源自cc._f()方法的打印。
后两行解析:aa._f()执行后无返回值,故为undefined。在apply执行解析后,cc._f()的this变为window,因此打印了window。因window中无_name属性,故输出undefined。
apply与call的参数传递区别
二、apply与call的区分
1.apply()
A.apply(B, [1,2,3])中,后续参数为arguments对象或类似数组的对象,它们会被自动解析为A的参数;
对于A.apply(B) / A.call(B),简言之,B先执行,执行后根据结果去执行A。此时,用A去执行B的内容代码,然后再执行自己的代码。
例如:
var f1 = function(a,b){
console.log(a+b)
}
var f2 = function(a,b,c){
console.log(a,b,c)
}
f2.apply(f1,[1,2])//1 2 undefined
先执行f1,f1执行后(f1是函数定义而非f1()执行方法,故console.log(a+b)这行代码并未执行,相当于初始化了代码f1),由于无返回值,结果为undefined。f2执行时this指向window;参数中的” [1,2] “,解析后变成f2的参数“1,2,undefined”,执行f2方法后,打印出1,2,undefined三个值。
2.call()
A.call(B, 1,2,3)中,后续参数均为独立的参数对象,它们会被自动解析为A的参数;
例如:
var f1 = function(a,b){
console.log(a+b)
}
var f2 = function(a,b,c){
console.log(a,b,c)
}
f2.call(f1,[1,2])//[1,2] undefined undefined
f2.call(f1,1,2)//1 2 undefined
参数中的” [1,2] “,因传入了一个数组,相当于只传入了第一个参数,b和c参数未传。解析后变成f2的参数“[1,2],undefined ,undefined”,执行f2方法后,打印出[1,2],undefined ,undefined 三个值。
apply与call的实际应用场景
三、apply与call带来的便利
1. push();
push参数以(a,b,c,d,e)形式传输,若需在一个数组基础上传输另一个数组的内容,可采用如下方式:
//apply用法
var arr = new Array(1,2,3)
var arr1 = new Array(11,21,31)
Array.prototype.push.apply(arr,arr1)
console.log(arr)//[1, 2, 3, 11, 21, 31]
//call用法
var arr = new Array(1,2,3)
var arr1 = new Array(11,21,31)
Array.prototype.push.call(arr,arr1[0],arr1[1],arr1[2])
console.log(arr)//[1, 2, 3, 11, 21, 31]
2. 数组利用Math求最大和最小值
apply和call的第一个参数,若为null或者undefined,则apply或call前面的函数会把this指向window
//apply的用法
var _maxNum = Math.max.apply(null,[1,3,2,4,5])
console.log(_maxNum)//5
var _minNum = Math.min.apply(null,[1,3,2,4,5])
console.log(_minNum)//1
//call的用法
var _maxNum = Math.max.call(null,1,3,2,4,5)
console.log(_maxNum)//5
var _minNum = Math.min.call(null,1,3,2,4,5)
console.log(_minNum)//1
总结
四、总结
简而言之,apply和call函数的第一个参数均用于替换this指向的对象;apply的第二个参数使用arguments或者类似数组的参数进行传参,call的第二个或以上的参数,使用独立单位,逐个进行传参;执行顺序是apply或call的第一个参数先执行得到结果,然后执行apply或call前面的函数,执行时用已执行结果所指代的this去执行。apply和call的使用除参数传递方式不同外,功能完全一致。
至此,文章全部内容结束,希望本文内容对大家的学习或工作具有参考学习价值,感谢支持。
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
