詳解JS幾種變量交換方式以及性能分析對比
前言
“兩個(gè)變量之間的值得交換”,這是一個(gè)經(jīng)典的話題,現(xiàn)在也有了很多的成熟解決方案,本文主要是列舉幾種常用的方案,進(jìn)行大量計(jì)算并分析對比。
起由
最近做某個(gè)項(xiàng)目時(shí),其中有一個(gè)需求是交換數(shù)組中的兩個(gè)元素。當(dāng)時(shí)使用的方法是:
arr = [item0,item1,...,itemN]; //最初使用這段代碼來交換第0個(gè)和第K(k<N)個(gè)元素 arr[0] = arr.splice(k, 1, arr[0])[0];
當(dāng)時(shí)覺得這種方法很優(yōu)雅,高逼格。。。
后來,業(yè)余時(shí)間又拿這個(gè)研究下了,順帶自己寫了個(gè)分析工具,和普通方式進(jìn)行對比。
結(jié)果,大大的出乎我的意料,這種方式的效率比我想象的要低的多。以下是其中一個(gè)測試結(jié)果的圖
于是,基于這點(diǎn),又研究了下其它的幾種數(shù)值交換的方式,一起整合進(jìn)入了分析工具中,才有了本文的這次總結(jié)。
JS變量交換的幾種方式
其實(shí)關(guān)于JS的變量交換,使用最廣泛的幾種方式基本已經(jīng)是前端人員必備的技能了,本文正好借此分析研究的契機(jī),列舉了本次分析中用到的幾種交換方式:
第一種:普通臨時(shí)變量交換方式
適用性: 適用于所有類型
代碼如下:
tmp = a; a = b; b = tmp;
簡要說明:
這是用到的最廣泛的一種方式,經(jīng)實(shí)戰(zhàn)測試分析,性能也很高
(在JS中,這種方式效率確實(shí)很高,而且就算是其它語言中,只要tmp變量提前創(chuàng)建,性能也不會(huì)很低,反而是一些雜技派和少數(shù)派性能方面很低)
基本上可以說: 經(jīng)典的才是最優(yōu)雅的
第二種:利用一個(gè)新的對象來進(jìn)行數(shù)據(jù)交換
適用性: 適用于所有類型
代碼如下:
a = {a : b, b : a}; b = a.b ;a = a.a;
簡要說明:
這種方式在實(shí)戰(zhàn)中應(yīng)用的很少
第三種:利用一個(gè)新的數(shù)組來進(jìn)行數(shù)據(jù)交換
適用性: 適用于所有類型
代碼如下:
a = [b, b=a][0];
簡要說明:
這種方式在各大論壇中都有看到有人使用,但經(jīng)測試實(shí)際性能并不高
第四種:利用數(shù)組交換變量(需EJS支持)
適用性: 適用于所有類型
代碼如下:
`[a, b] = [b, a];
簡要說明:
這也是在ES6出來后看到有人用的,實(shí)際在現(xiàn)有的瀏覽器中測試,性能很低
第五種:利用try catch交換
適用性: 適用于所有類型
代碼如下:
a=(function(){; try{return b} finally{b=a}} )();
簡要說明:
這種方法應(yīng)該是基本沒人使用的,也沒有什么實(shí)用性,而且性能也是屬于在各種方法中墊底的
第六種:異或操作交換變量第一種方式
適用性: 適用于數(shù)字或字符串
代碼如下:
a = (b = (a ^= b) ^ b) ^ a;
簡要說明:
異或方法在數(shù)字或字符串時(shí)用到的比較普遍,而且性能也不低
第七種:異或操作交換變量第二種方式
適用性: 適用于數(shù)字或字符串
代碼如下:
a ^=b; b ^=a; a ^=b;
簡要說明:
異或方法在數(shù)字或字符串時(shí)用到的比較普遍,而且性能也不低
第八種:數(shù)字之間的加減運(yùn)算來實(shí)現(xiàn),第一種加減方式
適用性: 僅適用于數(shù)字
代碼如下:
a = a + b; b = a - b; a = a - b;
簡要說明:
這種用法在只用于數(shù)字間的交換時(shí),性能也不弱
第九種:數(shù)字之間的加減運(yùn)算來實(shí)現(xiàn),第一種加減方式
適用性: 僅適用于數(shù)字
代碼如下:
a = b -a +(b = a);
簡要說明:
這種用法在只用于數(shù)字間的交換時(shí),性能也不弱
第十種:利用eval計(jì)算
適用性: 僅適用于數(shù)字和字符串
代碼如下:
eval("a="+b+";b="+a);
簡要說明:
這種方式僅用于研究,實(shí)戰(zhàn)慎用
這種模式執(zhí)行一萬次耗時(shí)等于其它執(zhí)行一億次...
第十一種:數(shù)組中,利用splice交換兩個(gè)元素的位置
適用性: 僅適用于數(shù)組元素
代碼如下:
arr[0] = arr.splice(2, 1, arr[0])[0];
簡要說明:
這種方式看起來挺優(yōu)雅的,但實(shí)際上性能遠(yuǎn)遠(yuǎn)比不上臨時(shí)變量那種
各種交換方式的性能對比
上述列舉了幾種方式都有一一做過對比分析,基本上可以得出的結(jié)論是:
還是老老實(shí)實(shí)的用回臨時(shí)變量交換吧,經(jīng)典,優(yōu)雅,而且保證不會(huì)出什么幺蛾子
性能對比截圖
分析結(jié)果1
以下截圖中的數(shù)據(jù)是,在chrome中運(yùn)行了一億次后得出的結(jié)論(每次運(yùn)行100萬次,一共100個(gè)循環(huán),得到的分析結(jié)果)
可以看出,tmp變量交換最快,try catch最慢
分析結(jié)果2
以下截圖數(shù)據(jù)是,在chrome (支持es6)中運(yùn)行了100萬次后得出的結(jié)論(每次運(yùn)行1萬次,一共100個(gè)循環(huán),得到的分析結(jié)果)
可以看出,eval最慢,splice性能較低,tmp變量交換很穩(wěn)定
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
用js實(shí)現(xiàn)的檢測瀏覽器和系統(tǒng)的函數(shù)
檢測各種瀏覽器、系統(tǒng)的JS代碼2009-04-04JS實(shí)現(xiàn)將對象轉(zhuǎn)化為數(shù)組的方法分析
這篇文章主要介紹了JS實(shí)現(xiàn)將對象轉(zhuǎn)化為數(shù)組的方法,結(jié)合實(shí)例形式分析了javascript操作及轉(zhuǎn)換json數(shù)組相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-01-01小程序如何獲取多個(gè)formId實(shí)現(xiàn)詳解
這篇文章主要介紹了小程序如何獲取多個(gè)formId實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09圖片動(dòng)畫橫條廣告帶上下滾動(dòng)的JS代碼
可以自定義廣告的圖片、鏈接、長、寬等。光標(biāo)移到圖片上會(huì)出現(xiàn)左右箭頭,有需要的朋友可以參考一下2013-10-10underscore之Chaining_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
本文通過文字說明與代碼的形式給大家介紹了underscore之Chaining的相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧2017-07-07Javascript如何實(shí)現(xiàn)對象扁平化實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于Javascript如何實(shí)現(xiàn)對象扁平化的扁平化處理簡而言之就是對對象中的對象提取出來,放在一個(gè)對象里面,形象的說就是把兒子的后代當(dāng)成自己的兒子,下面相關(guān)資料,需要的朋友可以參考下2022-11-11