JavaScript中,有了apply,为什么还要有call?

为什么js要设计两个如此相似的api出来呢?
我觉得,有apply就够了呀。
有没有大佬出来讲一讲。

注意我问的不是这两个api怎么用,用在什么场景下。我知道他们的区别,但我不明白这样设计的意图。

阅读 4k
4 个回答

一开始确实只有call,后来估计方便开发者处理参数引入了apply,但也导致apply的性能不如call。lodash库居然还定义了一个“更快的apply”,其内部就是利用call:

/**
 * A faster alternative to `Function#apply`, this function invokes `func`
 * with the `this` binding of `thisArg` and the arguments of `args`.
 *
 * @private
 * @param {Function} func The function to invoke.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {Array} args The arguments to invoke `func` with.
 * @returns {*} Returns the result of `func`.
 */
  function apply(func, thisArg, args) {
    switch (args.length) {
      case 0: return func.call(thisArg);
      case 1: return func.call(thisArg, args[0]);
      case 2: return func.call(thisArg, args[0], args[1]);
      case 3: return func.call(thisArg, args[0], args[1], args[2]);
    }
    return func.apply(thisArg, args);
  }

谈一谈个人的理解。
首先,在MDN里面,call是在ECMAScript第一版的规范里面规定的。而apply是在第三版的规范里面出现的。
call比apply更早出现。
其次,apply其实是对call的一个封装,apply性能会比call更差。可以把apply看成是call的一个语法糖。
apply的使用有时候更加方便,因为他会自动帮你把数组展开。但有时候你也并不想直接展开,而是直接传递一个数组。

反了。

先有的 call,再有的 apply

call 有先天不足,即必须显式的提前声明好这些形参。

你要非刨根问底的为啥不最开始一步到位直接有 apply,那只能说制订 ECMA-262 那帮人当时没考虑到。

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