为什么 call 比 apply 快?
这是一个非常有意思的问题。
在看源码的过程中,总会遇到这样的写法:
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 )
为什么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 快?相关推荐
- python多进程map比apply快_python 多进程读写 map
要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识. Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回 ...
- 再见 for 循环!pandas 提速 315 倍~
for是所有编程语言的基础语法,初学者为了快速实现功能,依懒性较强.但如果从运算时间性能上考虑可能不是特别好的选择. 本次东哥介绍几个常见的提速方法,一个比一个快,了解pandas本质,才能知道如何提 ...
- 在JavaScript中找到数组的最小/最大元素
如何轻松获得JavaScript数组的min或max元素? 伪代码示例: let array = [100, 0, 50]array.min() //=> 0 array.max() //=&g ...
- 2017-09-20 前端日报
2017-09-20 前端日报 精选 如何在 React Native 实现类微信小程序平台:WebView 调用原生组件 TCP/IP协议族 如何优雅的编写JavaScript代码 浅谈HTML5 ...
- 阿里云python自测答案_阿里云技能测试python初级中级高级
简介 偶尔发现,阿里云-开发者社区,里竟然有技能测试平台 覆盖知识面也较多 初级(65) 涉及知识点:Python语言的基本特性.编程环境.语法基础.数据结构,了解Python的网络编程与Web开发, ...
- 还在抱怨pandas运行速度慢?这几个方法会颠覆你的看法
前言 当大家谈到数据分析时,提及最多的语言就是Python和SQL.Python之所以适合数据分析,是因为它有很多第三方强大的库来协助,pandas就是其中之一.pandas的文档中是这样描述的: & ...
- python lambda if elif_Lambda包括if…elif…els
我不建议在这里使用apply:如果有更好的替代品,就应该避免使用. 例如,如果要对序列执行以下操作:if cond1: exp1 elif cond2: exp2 else: exp3 这通常是np. ...
- Pandas 秘籍:6~11
原文:Pandas Cookbook 协议:CC BY-NC-SA 4.0 译者:飞龙 六.索引对齐 在本章中,我们将介绍以下主题: 检查索引对象 生成笛卡尔积 索引爆炸 用不相等的索引填充值 追加来 ...
- 再见 for 循环!pandas 提速 315 倍!
点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 西陆蝉声唱,南冠客思深. 来源:P ...
- apply筛选 pandas_更快的pandas.apply搜索方法
python3中的字典类型用了哈希排列,速度很快.到底有多快呢. 最近写数据分析代码,有一个筛选程序,在使用pandas.apply的过程中,在apply过程中使用了loc函数,速度很慢.为了提高速度 ...
最新文章
- 如何把 DropDownList 某一个 Item 的 Text 改成粗体 ?
- 【MFC】1.Windows程序内部运行原理
- php判断目录是否有写的权限,php中判断文件空目录是否有读写权限的函数代码_php技巧...
- 工作342:消除平时环境的console
- prism v2之旅(7)
- Photoshop怎么实现图片局部马赛克
- 计算机输入输出接口是交接界面,计算机组成原理试题1
- ***检测(IDS)存在的问题及发展趋势
- GB28181协议——摄像机语音对讲
- 2022年高压电工操作证考试题库及在线模拟考试
- 关于HTTP GZIP解压问题
- DLL入口函数DllMain
- python pysynth随机生成中国风音乐旋律
- 后盾网向军零基础学PHP视频教程
- 《如何阅读一本书》章节要点整理
- 综合日语第一册第十二课
- 录音分享以及重命名功能小结
- IBM服务器代理商创业之路①
- 【游戏客户端】如何实现环形进度条
- 【小工具类】将一个十进制数转化成二进制/四进制/八进制/16进制
热门文章
- python 计算置信区间,Python求解正态分布置信区间
- 轻健身餐的市场前景如何?如何选择一个投资小、美食和健身餐清淡的品牌?
- ios第3天的气泡作业
- uniapp实现贪吃蛇小游戏
- SpringData JPA联表分页查询需要使用countQuery属性
- C++游戏《Flappy bird》
- java基础编程题_Java基础练习题:编程练习(1) - 菜鸟头头
- 镁光闪存颗粒对照表_最全的内存颗粒编码规则说明,教你看穿内存条到底用的什么颗粒...
- JVM上篇:内存与垃圾回收篇一--JVM与Java体系结构
- mysql中的int(11)到底代表什么意思?