We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
https://boycgit.github.io/fe-program-tips/#/javascript/arguments_to_array
有很多种方式将 arguments 转换成数组,那么哪一种方式是最优的?
为节约大伙儿的时间,这里先说一下结论:如果你想将 arguments 转换成数组,最好的方式是使用 rest 参数转换的方式(即使用 ... spread 操作符),比如:
...
function test(…args) { console.log(args) } test(1,2,3); // [1,2,3]点击复制错误复制成功
function test(…args) { console.log(args) } test(1,2,3); // [1,2,3]
原因是:性能是 最优 的,可读性也挺好。
想知道为什么的话,可以继续往下看。
arguments 对象是所有(非箭头)函数中都可用的局部变量,它是一个 “Array-Like” 对象,即 “像数组的对象”的意思,有些文章中也会翻译成 “伪数组对象”。(可以按索引取值、具有 length 属性,但不一定具备 push、concat 等数组方法,具体可参考文章伪数组(ArrayLike)内容)
arguments
length
push
concat
注意:箭头函数中并不存在 arguments 对象
本期 tip 并不去详细讲 arguments 对象的知识内容(具体知识内容可阅读本讲末尾的参考文章),本讲着重讲解把它转换成数组时的最佳实践。
浏览了许多技术文章,将 arguments 对象转换成数组基本是 4 种方式:
Array.prototype.slice.call(arguments)
[].slice.call(arguments)
Array.from(arguments)
for
let a = (...args) => args
大多数文章也仅仅是讲到这里为止,并没有继续讨论以上哪种方式最优。
接下来我们就用基准测试(Benchmark)的方式来量化上述那种方式性能更好。
在《做好准备:新的V8即将发布,Node 的性能正在改变》文中给了结论:
我将这文中提及的测试代码扔到 jsPerf 网站上(测试地址:https://jsperf.com/rest-arguments-slice ),运行结果如下:
jsPerf
图中数值越高代表性能越好,以上两幅图所反映的结果是一致的:
[].slice
Array.from
也可本地进行性能测试,测试代码在 这儿 获取;源码来自 官方提供的 benchmark 示例
因此,如果你想要将 arguments 转换成数组,那么毫无疑问应当使用 ES6 中的 rest 参数转换方式。
除了性能更好之外,rest 参数的用法相对于直接使用 arguments 还有如下优点:
rest
在这里我简单解答一些常见的疑惑:
Q: 为什么需要将 arguments 对象转换成数组?
A: 答案也简单,因为 Array 实例提供了很多数组方法,比如 .push、.concat 等,提供了更多数据操作方式,归根到底,转换成数组就是为了方便操作数据。
.push
.concat
Q: 既然经常要将 arguments 转换成数组,为什么最初不把 arguments 设计成数组格式呢?
A: 按照文章 《JavaScript arguments 对象全面介绍》所言, arguments 在语言的早期就引入了,当时的 Array 对象具有 4 个方法: toString、 join、 reverse 和 sort。arguments 继承于 Object 的很大原因是不需要这四个方法。(当时设计的人也不知道后续的发展会对 arguments 有这方面的强需求...变化无处不在..)
toString
join
reverse
sort
Q: 为什么需要 Array-Like 对象(伪数组对象)的存在?
Array-Like
A: 前面说了,转换成数组也是为了提供更多数据操作方式;其实 Array-Like 对象的存在,也是为了给数据提供更多的操作的可能,因为可以在对象上挂载很多 自定义 的操作方法,使用起来灵活度会很高。
Q: 上述讨论的数组转换结果,是否也适应于其他 “伪数组对象”?
A: 因为 arguments 也是“伪数组对象”,不难推而广之,上面讨论的数组转换的方式都可以应用在“伪数组对象”上;至于每个转换方法的性能如何,我因为没有单独去测试过,所以也不能妄下定论,大家可以自己写 benchmark 去测试一下(个人猜测应该结论也差不多)。
关注微信公众号,回复 “tips” + “期号” 获取往期 tip。(比如可以通过回复 “tips25” 获取 第 25 期 tips)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
https://boycgit.github.io/fe-program-tips/#/javascript/arguments_to_array
第 2 期 - 将 arguments 转换成数组的最佳实践
视频讲解
<iframe class="article-video" src="//player.bilibili.com/player.html?aid=81684736&cid=139770298&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>文字讲解
1、先讲结论
有很多种方式将 arguments 转换成数组,那么哪一种方式是最优的?
为节约大伙儿的时间,这里先说一下结论:如果你想将 arguments 转换成数组,最好的方式是使用 rest 参数转换的方式(即使用
...
spread 操作符),比如:原因是:性能是 最优 的,可读性也挺好。
想知道为什么的话,可以继续往下看。
2、原因分析
arguments
对象是所有(非箭头)函数中都可用的局部变量,它是一个 “Array-Like” 对象,即 “像数组的对象”的意思,有些文章中也会翻译成 “伪数组对象”。(可以按索引取值、具有length
属性,但不一定具备push
、concat
等数组方法,具体可参考文章伪数组(ArrayLike)内容)注意:箭头函数中并不存在
arguments
对象本期 tip 并不去详细讲 arguments 对象的知识内容(具体知识内容可阅读本讲末尾的参考文章),本讲着重讲解把它转换成数组时的最佳实践。
浏览了许多技术文章,将
arguments
对象转换成数组基本是 4 种方式:Array.prototype.slice.call(arguments)
进行转换,或者是使用等效方法[].slice.call(arguments)
;Array.from(arguments)
进行转换for
循环挨个将arguments
对象中的内容复制给新数组中let a = (...args) => args
;大多数文章也仅仅是讲到这里为止,并没有继续讨论以上哪种方式最优。
接下来我们就用基准测试(Benchmark)的方式来量化上述那种方式性能更好。
3、性能测试
在《做好准备:新的V8即将发布,Node 的性能正在改变》文中给了结论:
我将这文中提及的测试代码扔到
jsPerf
网站上(测试地址:https://jsperf.com/rest-arguments-slice ),运行结果如下:图中数值越高代表性能越好,以上两幅图所反映的结果是一致的:
for
循环方式转换[].slice
的方式性能较弱Array.from
进行转换因此,如果你想要将
arguments
转换成数组,那么毫无疑问应当使用 ES6 中的 rest 参数转换方式。除了性能更好之外,
rest
参数的用法相对于直接使用arguments
还有如下优点:4、Q & A
在这里我简单解答一些常见的疑惑:
Q: 为什么需要将
arguments
对象转换成数组?A: 答案也简单,因为 Array 实例提供了很多数组方法,比如
.push
、.concat
等,提供了更多数据操作方式,归根到底,转换成数组就是为了方便操作数据。Q: 既然经常要将
arguments
转换成数组,为什么最初不把arguments
设计成数组格式呢?A: 按照文章 《JavaScript arguments 对象全面介绍》所言,
arguments
在语言的早期就引入了,当时的 Array 对象具有 4 个方法:toString
、join
、reverse
和sort
。arguments
继承于 Object 的很大原因是不需要这四个方法。(当时设计的人也不知道后续的发展会对arguments
有这方面的强需求...变化无处不在..)Q: 为什么需要
Array-Like
对象(伪数组对象)的存在?A: 前面说了,转换成数组也是为了提供更多数据操作方式;其实
Array-Like
对象的存在,也是为了给数据提供更多的操作的可能,因为可以在对象上挂载很多 自定义 的操作方法,使用起来灵活度会很高。Q: 上述讨论的数组转换结果,是否也适应于其他 “伪数组对象”?
A: 因为
arguments
也是“伪数组对象”,不难推而广之,上面讨论的数组转换的方式都可以应用在“伪数组对象”上;至于每个转换方法的性能如何,我因为没有单独去测试过,所以也不能妄下定论,大家可以自己写 benchmark 去测试一下(个人猜测应该结论也差不多)。3、参考文章
关注微信公众号,回复 “tips” + “期号” 获取往期 tip。(比如可以通过回复 “tips25” 获取 第 25 期 tips)
The text was updated successfully, but these errors were encountered: