关于js call apply的一些疑问

  let a = [1, 2, 3, 4, 5, 6].shift.call([2, 4])
  let b = Math.max.apply([1, 2, 3])
  let c = Math.max.apply(null,[1, 2, 3])
  console.log(a);
  console.log(b);
  console.log(c);

为什么数组的shift方法不用传null就能使用,而math方法却要传null
a正常 b错误 c正常

阅读 1.9k
2 个回答

call 和 apply 非常相似, 相同点:

  1. call 和 apply 都是对函数对象的调用
  2. call 和 apply 第一个参数都是指定 this

他们的不同点是, call 的后续参数是展开的, apply 的后续参数是一个包含了所有参数的参数列表

以下三种完全等价:


console.log(Math.max(1, 2, 3))

console.log(Math.max.call(null, 1, 2, 3))

console.log(Math.max.apply(null, [1, 2, 3]))

而你的代码中第一个

let a = [1, 2, 3, 4, 5, 6].shift.call([2, 4])

应该是没有理解的情况下的误用:

  1. 首先 Arrayshift 方法没有参数
  2. 上述代码实际上是执行了这个:
[2, 4].shift() // 返回 2

原因是你替换了 shift 这个函数执行目标的 this 对象, 所以实际上已经在另一个数组上执行了 shift() 方法


建议细读文档

Array.prototype.shift
Function.prototype.call
Function.prototype.apply

首先 就没有 [.x.x.x.].shift.call()这种用法

.call 和 .apply 都是直接从原型对象获取方法,然后从传入两个参数(this(也就是执行的上下文环境), [...args])
所以你的 [1, 2, 3, 4, 5, 6].shift.call([2, 4])
等价于 Array.prototype.shift.call([2,4]) 这个 [2,4] 不是args参数而是当this使用的
就等价于 [2,4].shift();

所以 同理
Math.max.apply([1, 2, 3])
这个 [1,2,3] 其实当作this传进去的
但其实Math作为js内置实例是不能被继承的,而且调用不需要this上下文,只需要入参就好了
所以最终等价于 Math.max(); 因为你没传递任何参数进去

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题