前端Tips#2 - 將 arguments 轉換成Array的最佳實踐

本文同步自 JSCON簡時空 - 技術博客,點擊閱讀

視頻講解

視頻地址javascript

文字講解

一、先講結論

有不少種方式將 arguments 轉換成數組,那麼哪種方式是最優的?html

爲節約大夥兒的時間,這裏先說一下結論:若是你想將 arguments 轉換成數組,最好的方式是使用 rest 參數轉換的方式(即便用 ... spread 操做符),好比:前端

function test(…args) {
   console.log(args)
}
test(1,2,3); // [1,2,3]

緣由是:性能是 最優 的,可讀性也挺好。java

想知道爲何的話,能夠繼續往下看。node

二、緣由分析

arguments 對象是全部(非箭頭)函數中均可用的局部變量,它是一個 「Array-Like」 對象,即 「像數組的對象」的意思,有些文章中也會翻譯成 「僞數組對象」。(能夠按索引取值、具備 length 屬性,但不必定具有 pushconcat 等數組方法,具體可參考文章僞數組(ArrayLike)內容)git

!> 注意:箭頭函數中並不存在 arguments 對象github

本期 tip 並不去詳細講 arguments 對象的知識內容(具體知識內容可閱讀本講末尾的參考文章),本講着重講解把它轉換成數組時的最佳實踐。編程

瀏覽了許多技術文章,將 arguments 對象轉換成數組基本是 4 種方式:segmentfault

  1. 使用 Array.prototype.slice.call(arguments)進行轉換,或者是使用等效方法 [].slice.call(arguments);
  2. 使用 Array.from(arguments) 進行轉換
  3. 使用 for 循環挨個將 arguments 對象中的內容複製給新數組中
  4. 利用 ES6 中的 rest 參數轉換,let a = (...args) => args;

大多數文章也僅僅是講到這裏爲止,並無繼續討論以上哪一種方式最優。數組

接下來咱們就用基準測試(Benchmark)的方式來量化上述那種方式性能更好。

三、性能測試

在《作好準備:新的V8即將發佈,Node 的性能正在改變》文中給告終論:

result

我將這文中說起的測試代碼扔到 jsPerf 網站上(測試地址:https://jsperf.com/rest-argum... ),運行結果以下:

benchmark result

圖中數值越高表明性能越好,以上兩幅圖所反映的結果是一致的:

  1. 利用 ES6 中的 rest 參數轉換性能最好
  2. 其次使用 for 循環方式轉換
  3. [].slice 的方式性能較弱
  4. 最差的就是用 Array.from 進行轉換
也可本地進行性能測試,測試代碼在 這兒 獲取;源碼來自 官方提供的 benchmark 示例

所以,若是你想要將 arguments 轉換成數組,那麼毫無疑問應當使用 ES6 中的 rest 參數轉換方式。

除了性能更好以外,rest 參數的用法相對於直接使用 arguments 還有以下優勢:

  1. 箭頭函數和普通函數均可以使用。
  2. 更加靈活,接收參數的數量徹底自定義。
  3. 可讀性更好,參數都是在函數括號中定義的,不會忽然出現一個arguments,顯得很突兀。

四、Q & A

在這裏我簡單解答一些常見的疑惑:

Q: 爲何須要將 arguments 對象轉換成數組?

A: 答案也簡單,由於 Array 實例提供了不少數組方法,好比 .push.concat 等,提供了更多數據操做方式,歸根到底,轉換成數組就是爲了方便操做數據。

Q: 既然常常要將 arguments 轉換成數組,爲何最初不把 arguments 設計成數組格式呢?

A: 按照文章 《JavaScript arguments 對象全面介紹》所言, arguments 在語言的早期就引入了,當時的 Array 對象具備 4 個方法: toStringjoinreversesortarguments 繼承於 Object 的很大緣由是不須要這四個方法。(當時設計的人也不知道後續的發展會對 arguments 有這方面的強需求...變化無處不在..)

Q: 爲何須要 Array-Like 對象(僞數組對象)的存在?

A: 前面說了,轉換成數組也是爲了提供更多數據操做方式;其實 Array-Like 對象的存在,也是爲了給數據提供更多的操做的可能,由於能夠在對象上掛載不少 自定義 的操做方法,使用起來靈活度會很高。

Q: 上述討論的數組轉換結果,是否也適應於其餘 「僞數組對象」?

A: 由於 arguments 也是「僞數組對象」,不難推而廣之,上面討論的數組轉換的方式均可以應用在「僞數組對象」上;至於每一個轉換方法的性能如何,我由於沒有單獨去測試過,因此也不能妄下定論,你們能夠本身寫 benchmark 去測試一下(我的猜想應該結論也差很少)。

五、參考文章


關於 「前端Tips專欄」

前端Tips」專欄,隸屬於 JSCON 專欄系列,設計初衷是快速獲取前端小技巧知識,取材普遍,涵蓋前端編程諸多領域。設計初衷是快速消費類知識,因此每一個 tips 閱讀耗時大約 5 分鐘。爲方便讀者在不一樣場合閱讀,每篇 tips 配有視頻音頻文字,挑本身喜歡方便的就行。

有兩種方式獲取歷史 tips:

① 在公衆號內回 "tips" +"期號" 就能夠。例如:回覆 「tips25」 便可獲取第25期 tips
② 前往網站:https://boycgit.github.io/fe-...裏面提供了搜索功能

歡迎你們關注個人知識專欄,更多內容等你來挖掘

我的微信公衆號

相關文章
相關標籤/搜索