这是一个非常有意思的问题。

在看源码的过程中,总会遇到这样的写法:

var triggerEvents = function(events, args) {var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];switch (args.length) {case 0: while (  i < l) (ev = events[i]).callback.call(ev.ctx); return;case 1: while (  i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;case 2: while (  i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;case 3: while (  i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;default: while (  i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;}
};

( 代码来自 backbone )

作者会在参数为3个(包含3)以内时,优先使用 call 方法进行事件的处理。而当参数过多(多余3个)时,才考虑使用 apply 方法。
这个的原因就是 call 比 apply 快。
网上有很多例子全方位的证明了 call 比 apply 快。大家可以看看 call和apply的性能对比 这篇文章中的例子,很全面。或者你也可以自己写几个简单的,测试一下。这里要推荐一个神奇网站 jsperf ,用于测试 js 性能。
几个简单的例子:

为什么call 比 apply 快?
这里就要提到他们被调用之后发生了什么。

Function.prototype.apply (thisArg, argArray)

1、如果 IsCallable(Function)为false,即 Function 不可以被调用,则抛出一个 TypeError 异常。
2、如果 argArray 为 null 或未定义,则返回调用 Function 的 [[Call]] 内部方法的结果,提供thisArg 和一个空数组作为参数。
3、如果 Type(argArray)不是 Object,则抛出 TypeError 异常。
4、获取 argArray 的长度。调用 argArray 的 [[Get]] 内部方法,找到属性 length。 赋值给 len。
5、定义 n 为 ToUint32(len)。
6、初始化 argList 为一个空列表。
7、初始化 index 为 0。
8、循环迭代取出 argArray。重复循环 while(index < n)
         a、将下标转换成String类型。初始化 indexName 为 ToString(index).
         b、定义 nextArg 为 使用 indexName 作为参数调用argArray的[[Get]]内部方法的结果。
         c、将 nextArg 添加到 argList 中,作为最后一个元素。
         d、设置 index = index+1
9、返回调用 Function 的 [[Call]] 内部方法的结果,提供 thisArg 作为该值,argList 作为参数列表。

Function.prototype.call (thisArg [ , arg1 [ , arg2, … ] ] )

1、如果 IsCallable(Function)为 false,即 Function 不可以被调用,则抛出一个 TypeError 异常。
2、定义 argList 为一个空列表。
3、如果使用超过一个参数调用此方法,则以从arg1开始的从左到右的顺序将每个参数附加为 argList 的最后一个元素
4、返回调用func的[[Call]]内部方法的结果,提供 thisArg 作为该值,argList 作为参数列表。

我们可以看到,明显 apply 比 call 的步骤多很多。
由于 apply 中定义的参数格式(数组),使得被调用之后需要做更多的事,需要将给定的参数格式改变(步骤8)。 同时也有一些对参数的检查(步骤2),在 call 中却是不必要的。
另外一个很重要的点:在 apply 中不管有多少个参数,都会执行循环,也就是步骤 6-8,在 call 中也就是对应步骤3 ,是有需要才会被执行。

综上,call 方法比 apply 快的原因是 call 方法的参数格式正是内部方法所需要的格式。

catch me:

知乎:李佳怡

更多专业前端知识,请上 【猿2048】www.mk2048.com

为什么 call 比 apply 快?相关推荐

  1. python多进程map比apply快_python 多进程读写 map

    要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识. Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回 ...

  2. 再见 for 循环!pandas 提速 315 倍~

    for是所有编程语言的基础语法,初学者为了快速实现功能,依懒性较强.但如果从运算时间性能上考虑可能不是特别好的选择. 本次东哥介绍几个常见的提速方法,一个比一个快,了解pandas本质,才能知道如何提 ...

  3. 在JavaScript中找到数组的最小/最大元素

    如何轻松获得JavaScript数组的min或max元素? 伪代码示例: let array = [100, 0, 50]array.min() //=> 0 array.max() //=&g ...

  4. 2017-09-20 前端日报

    2017-09-20 前端日报 精选 如何在 React Native 实现类微信小程序平台:WebView 调用原生组件 TCP/IP协议族 如何优雅的编写JavaScript代码 浅谈HTML5 ...

  5. 阿里云python自测答案_阿里云技能测试python初级中级高级

    简介 偶尔发现,阿里云-开发者社区,里竟然有技能测试平台 覆盖知识面也较多 初级(65) 涉及知识点:Python语言的基本特性.编程环境.语法基础.数据结构,了解Python的网络编程与Web开发, ...

  6. 还在抱怨pandas运行速度慢?这几个方法会颠覆你的看法

    前言 当大家谈到数据分析时,提及最多的语言就是Python和SQL.Python之所以适合数据分析,是因为它有很多第三方强大的库来协助,pandas就是其中之一.pandas的文档中是这样描述的: & ...

  7. python lambda if elif_Lambda包括if…elif…els

    我不建议在这里使用apply:如果有更好的替代品,就应该避免使用. 例如,如果要对序列执行以下操作:if cond1: exp1 elif cond2: exp2 else: exp3 这通常是np. ...

  8. Pandas 秘籍:6~11

    原文:Pandas Cookbook 协议:CC BY-NC-SA 4.0 译者:飞龙 六.索引对齐 在本章中,我们将介绍以下主题: 检查索引对象 生成笛卡尔积 索引爆炸 用不相等的索引填充值 追加来 ...

  9. 再见 for 循环!pandas 提速 315 倍!

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 西陆蝉声唱,南冠客思深. 来源:P ...

  10. apply筛选 pandas_更快的pandas.apply搜索方法

    python3中的字典类型用了哈希排列,速度很快.到底有多快呢. 最近写数据分析代码,有一个筛选程序,在使用pandas.apply的过程中,在apply过程中使用了loc函数,速度很慢.为了提高速度 ...

最新文章

  1. 如何把 DropDownList 某一个 Item 的 Text 改成粗体 ?
  2. 【MFC】1.Windows程序内部运行原理
  3. php判断目录是否有写的权限,php中判断文件空目录是否有读写权限的函数代码_php技巧...
  4. 工作342:消除平时环境的console
  5. prism v2之旅(7)
  6. Photoshop怎么实现图片局部马赛克
  7. 计算机输入输出接口是交接界面,计算机组成原理试题1
  8. ***检测(IDS)存在的问题及发展趋势
  9. GB28181协议——摄像机语音对讲
  10. 2022年高压电工操作证考试题库及在线模拟考试
  11. 关于HTTP GZIP解压问题
  12. DLL入口函数DllMain
  13. python pysynth随机生成中国风音乐旋律
  14. 后盾网向军零基础学PHP视频教程
  15. 《如何阅读一本书》章节要点整理
  16. 综合日语第一册第十二课
  17. 录音分享以及重命名功能小结
  18. IBM服务器代理商创业之路①
  19. 【游戏客户端】如何实现环形进度条
  20. 【小工具类】将一个十进制数转化成二进制/四进制/八进制/16进制

热门文章

  1. python 计算置信区间,Python求解正态分布置信区间
  2. 轻健身餐的市场前景如何?如何选择一个投资小、美食和健身餐清淡的品牌?
  3. ios第3天的气泡作业
  4. uniapp实现贪吃蛇小游戏
  5. SpringData JPA联表分页查询需要使用countQuery属性
  6. C++游戏《Flappy bird》
  7. java基础编程题_Java基础练习题:编程练习(1) - 菜鸟头头
  8. 镁光闪存颗粒对照表_最全的内存颗粒编码规则说明,教你看穿内存条到底用的什么颗粒...
  9. JVM上篇:内存与垃圾回收篇一--JVM与Java体系结构
  10. mysql中的int(11)到底代表什么意思?