從 forEach 展開學(xué)習(xí) JavaScript 的一些循環(huán)方法

已知需求從數(shù)組中查詢滿足特定條件的值,我開始用的 forEach陷谱,因?yàn)橛泻芏嘀敌枰樵兝硬看味家h(huán)一遍數(shù)組,我就想直接用 for 循環(huán)是不是要快一些烟逊,于是想比較一下 for forEach map 三個誰快一些渣窜。

const tempArr = Array.from({ length: 1000 }).map(s => ({ name: ~~(Math.random() * 1000) }));

console.time('for');
const forArr = [];
for (let i = 0; i < tempArr.length; i++) {
  if (tempArr[i] === 233) forArr.push(tempArr[i]);
}
console.timeEnd('for');

console.time('forEach');
const forEachArr = [];
tempArr.forEach(s => {
  if (s === 233) forEachArr.push(s);
})
console.timeEnd('forEach');

console.time('map');
const mapArr = [];
tempArr.map(s => {
  if (s === 233) mapArr.push(s);
});
console.timeEnd('map');

經(jīng)過測試,這三者大概有 30% 的差距宪躯,但是速度并不是一直 for > forEach > map乔宿,運(yùn)行多次,有時候 for 可能最慢访雪,map 最快详瑞。

于是我打算上網(wǎng)搜一下,在看了一些文章和資料后臣缀,我突然意識到優(yōu)化不是這樣打的坝橡。

性能優(yōu)化什么的,應(yīng)該是底層優(yōu)化精置,而不是語法的選擇计寇,像這類語法糖更多的是提供語義化便捷性

  • forEach 可以更方便的循環(huán)遍歷
  • map 除了循環(huán)遍歷還會返回一個數(shù)組

“過早優(yōu)化是萬惡之源”氯窍,能力不夠的時候會往錯誤的方向使勁饲常。

那么回到問題,我是想要減少循環(huán)次數(shù)狼讨,那直接用對象的 key 取值更快啊。只需要處理一次原數(shù)組柒竞,就不用每次都循環(huán)了政供。

通過測試,我發(fā)現(xiàn) map 和 forEach 的差距并沒有那么大,于是我打算查看一下他們的實(shí)現(xiàn)布隔。

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {
  Array.prototype.map = function (callback/*, thisArg*/) {
    var T, A, k;
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }
    var O = Object(this);
    var len = O.length >>> 0;
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }
    if (arguments.length > 1) {
      T = arguments[1];
    }
    A = new Array(len);
    k = 0;
    while (k < len) {
      var kValue, mappedValue;
      if (k in O) {
        kValue = O[k];
        mappedValue = callback.call(T, kValue, k, O);
        A[k] = mappedValue;
      }
      k++;
    }
    return A;
  };
}
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function (callback/*, thisArg*/) {
    var T, k;
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }
    var O = Object(this);
    var len = O.length >>> 0;
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }
    if (arguments.length > 1) {
      T = arguments[1];
    }
    k = 0;
    while (k < len) {
      var kValue;
      if (k in O) {
        kValue = O[k];
        callback.call(T, kValue, k, O);
      }
      k++;
    }
  };
}

發(fā)現(xiàn)都是用到了 while 离陶,只是 map 多存了一個對象,對于目前前端的數(shù)據(jù)處理衅檀,這點(diǎn)消耗完全可以忽略招刨,但是可讀性就很重要了,明明不需要返回新數(shù)組哀军,結(jié)果使用了 map 沉眶,可能會給讀代碼的人造成一點(diǎn)點(diǎn)困擾。就像 div 可以做很多事杉适,但是官方還是推薦語義化標(biāo)簽谎倔。

好了,既然都寫到這里了猿推,俗話說“來都來了”片习,這里整理一下 JavaScript 中操作數(shù)組和對象的部分方法。

  • while
const arr = [...];
let k = 0;
while( k < arr.length ) {
  k++;
  // do something
}
  • for
  • for-of
  • for-in
const arr = [...];
for(let i = 0; i < arr.length; i++ ) {
  // do something
}
for(let i of arr ) {
  // do something
}

const dist = {};
for(let i in arr ) {
  // do something
}
  • forEach
const arr = [...];
arr.forEach((s,i)=>{
  // do something
});

// thisArg
class Counter {
  sum = 0;
  count = 0;
  add(array){
    array.forEach( s => {
      this.sum += s;
      ++this.count;
    },this)
  }
}
  • map
const arr = [...];
const newArr = arr.map((s,i) => {
  // do something
  return xxx;
});
  • reduce
    • 接受一個判斷函數(shù)
    • 迭代執(zhí)行該函數(shù)并返回最終結(jié)果
const arr= [3, 14,15, 9, 26];
const sum = arr.reduce(a,b) => a + b);
  • filter
    • 接收一個判斷函數(shù)
    • 返回一個滿足條件的數(shù)組
const arr= [3, 14,15, 9, 26];
const res = arr.filter(s => s > 10);  // [14,15,26]
  • every
    • 接收一個判斷函數(shù)
    • 返回 true / false
    • true:全滿足
    • false:至少有一個不滿足
const arr= [3, 14,15, 9, 26];
arr.every(s => s < 30);  // true
arr.every(s => s > 10); // false
  • some
    • 接收一個判斷函數(shù)
    • 返回 true / false
    • true:至少有一個滿足
    • false:全不滿足
const arr= [3, 14,15, 9, 26];
arr.some(s => s < 30);  // true
arr.some(s => s > 10);  // true
arr.some(s => s < 0);  // false
  • find
    • 接收一個判斷函數(shù)
    • 返回滿足條件的第一個值
const arr= [3, 14,15, 9, 26];
const res = arr.find(s => s > 13);  // 14
  • findIndex
    • 接收一個判斷函數(shù)
    • 返回滿足條件的第一個值的 index
const arr= [3, 14,15, 9, 26];
const resIndex = arr.findIndex(s => s > 13);  // 1

我是虛玩玩蹬叭,與君共勉~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末藕咏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秽五,更是在濱河造成了極大的恐慌孽查,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筝蚕,死亡現(xiàn)場離奇詭異卦碾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)起宽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門洲胖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坯沪,你說我怎么就攤上這事绿映。” “怎么了腐晾?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵叉弦,是天一觀的道長。 經(jīng)常有香客問我藻糖,道長淹冰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任巨柒,我火速辦了婚禮樱拴,結(jié)果婚禮上柠衍,老公的妹妹穿的比我還像新娘。我一直安慰自己晶乔,他們只是感情好珍坊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著正罢,像睡著了一般阵漏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翻具,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天履怯,我揣著相機(jī)與錄音,去河邊找鬼呛占。 笑死虑乖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晾虑。 我是一名探鬼主播疹味,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帜篇!你這毒婦竟也來了糙捺?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤笙隙,失蹤者是張志新(化名)和其女友劉穎洪灯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竟痰,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡签钩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了坏快。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铅檩。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖莽鸿,靈堂內(nèi)的尸體忽然破棺而出昧旨,到底是詐尸還是另有隱情,我是刑警寧澤祥得,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布兔沃,位于F島的核電站,受9級特大地震影響级及,放射性物質(zhì)發(fā)生泄漏乒疏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一饮焦、第九天 我趴在偏房一處隱蔽的房頂上張望缰雇。 院中可真熱鬧入偷,春花似錦追驴、人聲如沸械哟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽暇咆。三九已至,卻和暖如春丙曙,著一層夾襖步出監(jiān)牢的瞬間爸业,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工亏镰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扯旷,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓索抓,卻偏偏與公主長得像钧忽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逼肯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容