call和apply的核心区别在于参数传递方式:call要求逐个列出参数,apply则接受数组或类数组作为第二个参数;二者this绑定规则、执行时机及返回值行为完全相同。

call 和 apply 的核心区别,就落在参数怎么传上:一个挨个列,一个打包成数组。
参数传递方式不同
call 要求把参数一个一个写出来,位置对应函数形参顺序:
-
语法:
fn.call(thisArg, arg1, arg2, arg3) - 适合已知参数个数、变量明确的场景,比如
greet.call(person, 'Hi', 'there')
apply 则强制第二个参数是数组(或类数组),内部自动展开:
-
语法:
fn.apply(thisArg, [arg1, arg2, arg3])或fn.apply(thisArg, arguments) - 适合参数来自数组、动态生成、数量不确定的情况,比如
Math.max.apply(null, numbersArray)
thisArg 的处理规则完全一致
两者第一个参数都是用来指定 this 指向的对象,行为一模一样:
- 传
null或undefined:非严格模式下 this 指向全局对象(如window),严格模式下保持原值 - 传原始值(如字符串、数字):非严格模式下自动包装为对象,严格模式下不转换
- 不传第一个参数:等同于传
undefined
执行时机与返回值也相同
它们都立刻调用函数,且 this 绑定只对这一次生效:
- 执行后返回函数本身的返回值,比如
sum.call(null, 2, 3)返回5 - 不会改变原函数,后续再调用
sum(),this 仍按默认规则确定 - 若需多次复用同一 this,应使用
bind,而不是反复 call/apply
典型实用场景对比
有些操作天然偏向某一种写法:
- 借用数组方法处理类数组对象:常用
Array.prototype.slice.call(arguments)(call 更直观) - 求数组最大值:必须用
Math.max.apply(null, arr)(因为Math.max不接受数组) - 构造函数继承:常写
Parent.call(this, name, age)(参数固定,语义清晰)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











