4個錯誤使用JavaScript數組方法的案例

来源:https://www.cnblogs.com/fundebug/archive/2018/09/06/make_better_use_of_arrays.html
-Advertisement-
Play Games

譯者按: 做一個有追求的工程師,代碼不是隨便寫的! 原文: "Here’s how you can make better use of JavaScript arrays" 譯者: "Fundebug" 為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用於學習。 小編推薦: ...


譯者按: 做一個有追求的工程師,代碼不是隨便寫的!

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用於學習。

小編推薦:Fundebug專註於JavaScript、微信小程式、微信小游戲,Node.js和Java線上bug實時監控。真的是一個很好用的bug監控服務,眾多大佬公司都在使用。

我保證這是一篇可以快速閱讀並吸收的文章。在過去的幾個月里,我檢查的所有的pull request中,都犯了這4個的錯誤。我寫這篇文章的另一個原因在於我自己也犯過這些錯。我們來看看如何正確地使用它們!

1. 不要使用Array.indexOf,使用Array.includes

“如果你要在數組中查找元素,使用Array.indexOf!”。記得在我學習JavaScript課程時候,有這樣一句話。這句話沒錯,確實可以這麼使用!

根據MDN文檔:“Array.indexOf會返回被查找元素第一個匹配的位置的下標。”因此,如果後面需要用到這個索引,Array.indexOf是一個很好的解法。

但是,我們要解決的問題是:查找數組中是否包含某個元素。這是一個Yes/No的問題,是一個返回布爾類型的真假問題。因此,我建議使用Array.includes,它會返回一個布爾值。

'use strict';

const characters = [
  'ironman',
  'black_widow',
  'hulk',
  'captain_america',
  'hulk',
  'thor',
];

console.log(characters.indexOf('hulk'));
// 2
console.log(characters.indexOf('batman'));
// -1

console.log(characters.includes('hulk'));
// true
console.log(characters.includes('batman'));
// false

2. 不要使用Array.filter,使用Array.find

Array.filter是一個很有用的函數,它返回一個滿足過濾條件的新數組。正如其名字表達的含義,它是用來做過濾的。

但是,如果我們知道我們要的結果只有一個元素的時候,我就不建議使用它了。比如,如果我們的回調函數定義用一個唯一的ID來過濾,那麼結果必然唯一了。在這個情況下,Array.filter會返回只有一個元素的數組。因為既然能通過一個特定的ID來查找,我們已經確定只有一個元素了,那麼使用數組就沒有意義。

另外,我們再來聊聊性能問題。為了返回所有匹配的元素,Array.filter需要查找整個數組。可以想象一下,如果有上百個元素滿足過濾條件,那麼返回的數組就很大。

為了避免這樣的情況,我建議使用Array.find。它僅僅返回第一個滿足過濾條件的元素。而且,Array.find會在查找到第一個滿足條件的元素後就結束執行,而不會查找整個數組。

'use strict';

const characters = [
  { id: 1, name: 'ironman' },
  { id: 2, name: 'black_widow' },
  { id: 3, name: 'captain_america' },
  { id: 4, name: 'captain_america' },
];

function getCharacter(name) {
  return character => character.name === name;
}

console.log(characters.filter(getCharacter('captain_america')));
// [
//   { id: 3, name: 'captain_america' },
//   { id: 4, name: 'captain_america' },
// ]

console.log(characters.find(getCharacter('captain_america')));
// { id: 3, name: 'captain_america' }

3. 不要使用Array.find,使用Array.some

我承認我犯過很多次錯誤。後來,一個很要好的朋友讓我去看看MDN的文檔,說有更好的解決方案。這個情況和剛剛提到的Array.indexOf/Array.includes很像。

在前面的例子中,我們看到Array.find接受一個過濾函數,返回滿足的元素。那麼,如果我們要查找一個數組是否包含某個元素的時候,Array.find是否是最佳的方案呢?可能不是,因為它返回的是元素具體的值,而不是布爾值。

我推薦大家使用Array.some,它會返回布爾值。

'use strict';

const characters = [
  { id: 1, name: 'ironman', env: 'marvel' },
  { id: 2, name: 'black_widow', env: 'marvel' },
  { id: 3, name: 'wonder_woman', env: 'dc_comics' },
];

function hasCharacterFrom(env) {
  return character => character.env === env;
}

console.log(characters.find(hasCharacterFrom('marvel')));
// { id: 1, name: 'ironman', env: 'marvel' }

console.log(characters.some(hasCharacterFrom('marvel')));
// true

4. 不要使用Array.map和Array.filter組合,使用Array.reduce

Array.reduce有點難以理解!但是,如果我們每次在同時使用Array.filter和Array.map的時候,你是否覺察到需要點東西,對不?

我的意思是:我們對整個數組迴圈了2遍。第一次是過濾返回一個新的數組,第二次通過map又構造一個新的數組。我們使用了兩個數組方法,每一個方法都有各自的回調函數,而且Array.filter返回的數組以後再也不會用到。

為了避免低效率,我建議使用Array.reduce。同樣的結果,更優雅的代碼!請看下麵的例子:

'use strict';

const characters = [
  { name: 'ironman', env: 'marvel' },
  { name: 'black_widow', env: 'marvel' },
  { name: 'wonder_woman', env: 'dc_comics' },
];

console.log(
  characters
    .filter(character => character.env === 'marvel')
    .map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
);
// [
//   { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
//   { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]

console.log(
  characters
    .reduce((acc, character) => {
      return character.env === 'marvel'
        ? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
        : acc;
    }, [])
)
// [
//   { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
//   { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]

備註

malgosiastp and David Piepgrass在評論中提到:在使用Array.find和Array.includes前請註意檢查相容性,因為最新的IE不支持。

關於Fundebug

Fundebug專註於JavaScript、微信小程式、微信小游戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了6億+錯誤事件,得到了Google、360、金山軟體等眾多知名用戶的認可。歡迎免費試用!

版權聲明:
轉載時請註明作者Fundebug以及本文地址:
https://blog.fundebug.com/2018/09/06/make-better-use-of-arrays/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一. perror 錯誤代碼查看工具 在mysql 的使用過程中,可能會出現各種各樣的error。這些error有些是由於操作系統引起的,比如文件或者目錄不存在等等,使用perror的作用就是解釋這些錯誤代碼的詳細含義。 perror 使用方法如下: 例如:指定錯誤號30和60分別是指什麼錯誤 在M ...
  • 由於mysql預設8小時連接無訪問,就會斷開.為此查了一下資料,有同種比較簡單的解決方案: 1. 增加 MySQL 的 wait_timeout 屬性的值。 修改 /etc/mysql/my.cnf文件,在 [mysqld] 節中設置: # Set a connection to wait 8hou ...
  • 使用SSMS資料庫管理工具修改DEFAULT約束 1、連接資料庫、選擇數據表-》右鍵點擊-》選擇設計。 2、在表設計器視窗-》選中要修改的數據列-》在列屬性中找到預設值綁定-》進行修改。 3、點擊保存(或者ctrl+s)-》關閉表設計器-》刷新表-》重新打開表設計器查看。 使用T-SQL腳本修改DE ...
  • 註:原文轉自 https://blog.csdn.net/zsg88/article/details/73715947 ,僅用作為方便查閱 一 所需軟體:Redis、Ruby語言運行環境、Redis的Ruby驅動redis-xxxx.gem、創建Redis集群的工具redis-trib.rb 二 安 ...
  • 在安卓開發過程中,當點擊HOME鍵,將app運行在後臺時,然後再點擊app圖標進入時,遇到瞭如下兩種情況: 1、每次打開時,app的入口頁面總是被執行。 2、當運行記憶體被其它應用占用完時,在進入app時,home時的當前頁面數據沒有被清除(待進一步確認),此時頁面正常,點擊返回鍵之後顯示的頁面數據被 ...
  • 一、具體問題 開發的過程中,發現某個界面部分圖片的顯示出現了問題只顯示占點陣圖片,取出圖片的url在瀏覽器卻是能打開的,各種嘗試甚至找同行的朋友幫忙在他們項目里展示都會存在問題,最終發現通過第三方框架SDWebImage或者YYWebImage下載帶有逗號的url圖片鏈接都會下載失敗,在下載方法完成的 ...
  • 不用管我下麵的第一個答案。我讀得太快了。 看起來這是一個簡單的例子,文件撒謊-或者至少是被誤解了。幸運的是,代碼並不是那麼簡單,而且gson是一個開源項目。 這是 JsonObject.get(String): 這裡是 members人口: 添加到 members是為Java類中定義的每個成員創建的 ...
  • 安卓開發者官方網站:https://developer.android.google.cn Android Studio下載地址:https://developer.android.google.cn/studio/ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...