JavaScript之數組方法詳解

JavaScript之數組方法詳解

    • 一、數組的創建與基礎特性
      • 1.1 數組的創建方式
      • 1.2 數組的核心特性
    • 二、修改原數組的方法
      • 2.1 添加/刪除元素
        • 2.1.1 `push()`:尾部添加元素
        • 2.1.2 `pop()`:尾部刪除元素
        • 2.1.3 `unshift()`:頭部添加元素
        • 2.1.4 `shift()`:頭部刪除元素
        • 2.1.5 `splice()`:指定位置添加/刪除
      • 2.2 排序與反轉
        • 2.2.1 `reverse()`:反轉數組
        • 2.2.2 `sort()`:排序數組
    • 三、不修改原數組的方法
      • 3.1 數組截取與合并
        • 3.1.1 `slice()`:截取子數組
        • 3.1.2 `concat()`:合并數組
      • 3.2 元素查找
        • 3.2.1 `indexOf()`與`lastIndexOf()`:查找索引
        • 3.2.2 `includes()`:判斷元素是否存在
        • 3.2.3 `find()`與`findIndex()`:查找符合條件的元素
      • 3.3 數組轉換
        • 3.3.1 `join()`:數組轉字符串
        • 3.3.2 `toString()`:數組轉字符串(簡化版)
    • 四、遍歷與迭代方法
      • 4.1 基礎遍歷
        • 4.1.1 `forEach()`:遍歷元素
      • 4.2 映射與過濾
        • 4.2.1 `map()`:映射新數組
        • 4.2.2 `filter()`:過濾元素
      • 4.3 聚合與檢測
        • 4.3.1 `reduce()`:累加計算
        • 4.3.2 `every()`與`some()`:條件檢測
    • 五、方法對比與最佳實踐
      • 5.1 方法選擇指南
      • 5.2 性能與注意事項
    • 六、常見問題與避坑指南
      • 6.1 `sort()`的默認排序陷阱
      • 6.2 `indexOf()`無法識別`NaN`
      • 6.3 `map()`返回新數組的長度不變

數組是JavaScript中最常用的數據結構之一,掌握數組方法是高效處理數據的基礎,本文我將系統梳理JavaScript數組的常用方法,從基礎的添加刪除到復雜的遍歷轉換,并結合實例解析每種方法的用法、特性及適用場景,幫你徹底搞懂數組操作的核心技巧。

一、數組的創建與基礎特性

在學習方法之前,先回顧數組的創建方式,這是后續操作的基礎:

1.1 數組的創建方式

// 1. 字面量方式(最常用)
const arr1 = [1, 2, 3];// 2. 構造函數方式
const arr2 = new Array(3); // 創建長度為3的空數組([ , , ])
const arr3 = new Array(1, 2, 3); // 創建包含元素的數組([1,2,3])// 3. 靜態方法創建(ES6+)
const arr4 = Array.of(1, 2, 3); // 類似字面量,避免new Array的歧義
const arr5 = Array.from([1, 2, 3], x => x * 2); // 從類數組/可迭代對象創建并映射([2,4,6])

1.2 數組的核心特性

  • 動態長度:數組長度可自動擴展(如arr.push(4)會增加長度)
  • 元素類型不限:可包含數字、字符串、對象等任意類型
  • 索引從0開始:通過arr[index]訪問元素

二、修改原數組的方法

這類方法會直接改變原數組,操作時需注意對原數據的影響。

2.1 添加/刪除元素

2.1.1 push():尾部添加元素
const fruits = ['apple', 'banana'];
const newLength = fruits.push('orange', 'grape'); // 添加多個元素
console.log(fruits); // ['apple', 'banana', 'orange', 'grape']
console.log(newLength); // 4(返回新長度)

特性:接受任意數量參數,添加到數組末尾,返回新長度。

2.1.2 pop():尾部刪除元素
const lastFruit = fruits.pop(); // 刪除最后一個元素
console.log(fruits); // ['apple', 'banana', 'orange']
console.log(lastFruit); // 'grape'(返回被刪除的元素)

特性:無參數,刪除最后一個元素,返回被刪除元素。

2.1.3 unshift():頭部添加元素
const newLength = fruits.unshift('mango'); // 頭部添加
console.log(fruits); // ['mango', 'apple', 'banana', 'orange']
console.log(newLength); // 4(返回新長度)

特性:接受任意數量參數,添加到數組頭部,返回新長度(性能比push()差,因需移動所有元素)。

2.1.4 shift():頭部刪除元素
const firstFruit = fruits.shift(); // 刪除第一個元素
console.log(fruits); // ['apple', 'banana', 'orange']
console.log(firstFruit); // 'mango'(返回被刪除元素)

特性:無參數,刪除第一個元素,返回被刪除元素(性能較差,同unshift())。

2.1.5 splice():指定位置添加/刪除
const numbers = [1, 2, 3, 4, 5];// 1. 刪除:splice(起始索引, 刪除數量)
const deleted = numbers.splice(2, 2); // 從索引2開始刪除2個元素
console.log(numbers); // [1, 2, 5]
console.log(deleted); // [3, 4](返回被刪除元素數組)// 2. 添加:splice(起始索引, 0, 添加元素1, ...)
numbers.splice(2, 0, 3, 4); // 從索引2開始,刪除0個,添加3和4
console.log(numbers); // [1, 2, 3, 4, 5](恢復原數組)// 3. 替換:splice(起始索引, 刪除數量, 替換元素)
numbers.splice(1, 2, 'a', 'b'); // 從索引1刪除2個,添加'a','b'
console.log(numbers); // [1, 'a', 'b', 4, 5]

特性:功能強大,可同時完成添加和刪除,返回被刪除元素數組(若未刪除則返回空數組)。

2.2 排序與反轉

2.2.1 reverse():反轉數組
const arr = [1, 2, 3];
arr.reverse();
console.log(arr); // [3, 2, 1]

特性:直接反轉原數組,返回反轉后的數組(與原數組引用相同)。

2.2.2 sort():排序數組
// 1. 默認排序(按字符串Unicode碼點,可能不符合預期)
const nums = [10, 2, 23];
nums.sort(); 
console.log(nums); // [10, 2, 23](錯誤排序,因'10'在'2'前)// 2. 數值升序排序(傳入比較函數)
nums.sort((a, b) => a - b); 
console.log(nums); // [2, 10, 23]// 3. 數值降序排序
nums.sort((a, b) => b - a); 
console.log(nums); // [23, 10, 2]// 4. 對象數組排序(按age屬性升序)
const users = [{ name: 'Bob', age: 25 },{ name: 'Alice', age: 20 }
];
users.sort((a, b) => a.age - b.age);
console.log(users); // [Alice(20), Bob(25)]

特性:默認按字符串排序,需傳入比較函數(a,b) => a - b(升序)或(a,b) => b - a(降序)實現數值排序;直接修改原數組,返回排序后的數組。

三、不修改原數組的方法

這類方法會返回新數組或其他結果,原數組保持不變,適合函數式編程。

3.1 數組截取與合并

3.1.1 slice():截取子數組
const arr = [1, 2, 3, 4, 5];// 1. slice(起始索引, 結束索引):含頭不含尾
const sub1 = arr.slice(1, 4); // 從索引1到3(不包含4)
console.log(sub1); // [2, 3, 4]// 2. 省略結束索引:截取到末尾
const sub2 = arr.slice(2); // 從索引2到末尾
console.log(sub2); // [3, 4, 5]// 3. 負數索引:從末尾開始計算
const sub3 = arr.slice(-3, -1); // 從倒數第3到倒數第2(索引2和3)
console.log(sub3); // [3, 4]

特性:返回新數組(原數組不變),參數支持負數(表示從末尾開始),slice(0)可用于復制數組。

3.1.2 concat():合并數組
const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [5];// 合并多個數組
const merged = arr1.concat(arr2, arr3, 6); // 可添加非數組元素
console.log(merged); // [1, 2, 3, 4, 5, 6]
console.log(arr1); // [1, 2](原數組不變)

特性:合并多個數組或值,返回新數組(原數組不變),類似ES6的擴展運算符[...arr1, ...arr2]

3.2 元素查找

3.2.1 indexOf()lastIndexOf():查找索引
const fruits = ['apple', 'banana', 'apple', 'orange'];// indexOf(元素, 起始索引):從前往后找,返回首次出現的索引
console.log(fruits.indexOf('apple')); // 0
console.log(fruits.indexOf('apple', 1)); // 2(從索引1開始找)
console.log(fruits.indexOf('grape')); // -1(未找到)// lastIndexOf(元素):從后往前找,返回最后出現的索引
console.log(fruits.lastIndexOf('apple')); // 2

特性indexOf從頭部開始,lastIndexOf從尾部開始;返回元素索引,未找到返回-1;使用嚴格相等(===)比較,無法查找引用類型元素。

3.2.2 includes():判斷元素是否存在
const nums = [1, 2, 3, NaN];// 基礎用法
console.log(nums.includes(2)); // true
console.log(nums.includes(5)); // false// 特殊:能識別NaN(indexOf不能)
console.log(nums.includes(NaN)); // true
console.log(nums.indexOf(NaN)); // -1(indexOf的缺陷)

特性:返回布爾值(是否包含元素),支持NaN判斷(比indexOf更友好),第二個參數可指定起始索引。

3.2.3 find()findIndex():查找符合條件的元素
const users = [{ id: 1, name: 'Alice' },{ id: 2, name: 'Bob' },{ id: 3, name: 'Alice' }
];// find(回調函數):返回第一個符合條件的元素
const alice = users.find(user => user.name === 'Alice');
console.log(alice); // { id: 1, name: 'Alice' }// findIndex(回調函數):返回第一個符合條件的元素索引
const aliceIndex = users.findIndex(user => user.name === 'Alice');
console.log(aliceIndex); // 0// 未找到時
console.log(users.find(user => user.id === 10)); // undefined
console.log(users.findIndex(user => user.id === 10)); // -1

特性:接受回調函數(item, index, arr) => 條件,返回第一個符合條件的元素(find)或索引(findIndex);適合查找對象數組,支持復雜條件。

3.3 數組轉換

3.3.1 join():數組轉字符串
const arr = ['a', 'b', 'c'];// 1. 默認用逗號分隔
console.log(arr.join()); // "a,b,c"// 2. 指定分隔符
console.log(arr.join('-')); // "a-b-c"// 3. 空字符串分隔(拼接成連續字符串)
console.log(arr.join('')); // "abc"

特性:將數組元素拼接為字符串,返回字符串;與String.split()互為逆操作。

3.3.2 toString():數組轉字符串(簡化版)
const arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"(等價于join())

特性:默認用逗號分隔,功能簡單,不如join()靈活。

四、遍歷與迭代方法

這類方法用于遍歷數組并執行操作,是處理數組數據的核心工具。

4.1 基礎遍歷

4.1.1 forEach():遍歷元素
const nums = [1, 2, 3];
let sum = 0;// forEach(回調函數):無返回值
nums.forEach((num, index, arr) => {sum += num;console.log(`索引${index}的值:${num}`);
});
console.log('總和:', sum); // 6

特性:無返回值(undefined),無法通過break中斷遍歷(需用try/catchreturn跳過當前元素);適合簡單的遍歷操作。

4.2 映射與過濾

4.2.1 map():映射新數組
const numbers = [1, 2, 3, 4];// map(回調函數):返回新數組(每個元素為回調返回值)
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]
console.log(numbers); // [1, 2, 3, 4](原數組不變)// 對象數組映射
const users = [{ name: 'A' }, { name: 'B' }];
const names = users.map(user => user.name);
console.log(names); // ['A', 'B']

特性:返回新數組(長度與原數組相同),原數組不變;適合數據轉換(如從對象數組中提取特定屬性)。

4.2.2 filter():過濾元素
const numbers = [1, 2, 3, 4, 5, 6];// filter(回調函數):返回符合條件的元素組成的新數組
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6]// 對象數組過濾
const users = [{ name: 'A', age: 17 },{ name: 'B', age: 20 },{ name: 'C', age: 25 }
];
const adults = users.filter(user => user.age >= 18);
console.log(adults); // [B(20), C(25)]

特性:返回新數組(包含所有符合條件的元素),原數組不變;適合數據篩選。

4.3 聚合與檢測

4.3.1 reduce():累加計算
const numbers = [1, 2, 3, 4];// reduce(回調函數, 初始值):返回累加結果
const sum = numbers.reduce((acc, num) => {return acc + num; // acc為累加器,num為當前元素
}, 0); // 初始值為0
console.log('總和:', sum); // 10// 計算數組中每個元素出現的次數
const fruits = ['apple', 'banana', 'apple'];
const count = fruits.reduce((acc, fruit) => {acc[fruit] = (acc[fruit] || 0) + 1;return acc;
}, {}); // 初始值為對象
console.log(count); // { apple: 2, banana: 1 }

特性:從左到右遍歷,通過累加器acc聚合結果,功能強大(可實現summaxgroupBy等);reduceRight()從右到左遍歷,用法類似。

4.3.2 every()some():條件檢測
const scores = [80, 90, 75, 60];// every():所有元素都符合條件才返回true
const allPass = scores.every(score => score >= 60);
console.log(allPass); // true(所有分數≥60)// some():至少一個元素符合條件就返回true
const hasExcellent = scores.some(score => score >= 90);
console.log(hasExcellent); // true(有一個分數≥90)

特性every類似“邏輯與”(全滿足),some類似“邏輯或”(有一個滿足);返回布爾值,且會短路(every遇到不滿足的元素立即返回falsesome遇到滿足的立即返回true)。

五、方法對比與最佳實踐

5.1 方法選擇指南

需求場景推薦方法替代方法
尾部添加元素push()splice(arr.length, 0, x)
尾部刪除元素pop()splice(arr.length-1, 1)
截取子數組slice()-
數組映射(轉換)map()-
數組過濾filter()-
累加計算reduce()forEach()(較繁瑣)
查找對象數組元素find()/findIndex()forEach()(需手動判斷)
判斷元素是否存在includes()indexOf() !== -1

5.2 性能與注意事項

  • 修改原數組 vs 返回新數組
    • 需保留原數組時,優先用slice()map()等不修改原數組的方法;
    • 頻繁操作大型數組時,push()concat()性能更好(因concat()返回新數組)。
  • 遍歷中斷
    • forEach()無法用break中斷,若需中斷可改用for循環或some()(通過return true中斷)。
  • 引用類型處理
    • 數組方法對對象元素的操作會影響原對象(因對象是引用傳遞):
    const users = [{ name: 'A' }];
    users.map(user => { user.age = 18; }); // 修改原對象
    console.log(users); // [{ name: 'A', age: 18 }]
    

六、常見問題與避坑指南

6.1 sort()的默認排序陷阱

const nums = [10, 2, 23];
nums.sort(); // 錯誤:按字符串排序,結果[10, 2, 23]
nums.sort((a, b) => a - b); // 正確:數值升序,結果[2, 10, 23]

解決方案:始終傳入比較函數處理數值排序。

6.2 indexOf()無法識別NaN

const arr = [NaN];
console.log(arr.indexOf(NaN)); // -1(錯誤)
console.log(arr.includes(NaN)); // true(正確)

解決方案:判斷NaN時用includes(),不用indexOf()

6.3 map()返回新數組的長度不變

const arr = [1, 2, 3];
const newArr = arr.map(num => {if (num > 1) return num * 2;// 未返回值時,默認返回undefined
});
console.log(newArr); // [undefined, 4, 6](長度仍為3)

解決方案map()適合“一對一”轉換,若需過濾元素應配合filter()

const newArr = arr.filter(num => num > 1).map(num => num * 2); // [4, 6]

總結:數組方法的核心要點

  1. 區分修改與不修改原數組的方法,根據是否需要保留原數據選擇;
  2. 遍歷與轉換方法map()filter()reduce())是處理復雜數據的核心,需熟練掌握;
  3. 查找方法中,find()適合對象數組,includes()適合簡單元素判斷;
  4. 注意方法的性能差異和特殊場景(如sort()的比較函數、includes()NaN的支持)。

若這篇內容幫到你,動動手指支持下!關注不迷路,干貨持續輸出!
ヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノ

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88029.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88029.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88029.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

品牌增長困局突圍:大模型時代,AI 如何幫我的品牌少走彎路?

AI時代對企業戰略的沖擊與機遇 在當今瞬息萬變的商業環境中,大模型的崛起正以前所未有的力量重塑著各行各業的競爭格局。傳統的市場營銷、品牌傳播模式正在被顛覆,消費者獲取信息、認知品牌的方式發生了根本性變化。如果說過去十年是“互聯網”的時代&am…

從單體到微服務:Spring Cloud 開篇與微服務設計

一、單體架構的核心痛點與微服務化目標 1. 單體架構的致命缺陷問題表現后果可維護性差百萬行代碼耦合,修改一處需全量測試迭代周期長,創新停滯擴展性受限無法按模塊獨立擴縮容(如訂單模塊需擴容時,用戶模塊被迫一起擴容&#xff0…

篇二 OSI七層模型,TCP/IP四層模型,路由器與交換機原理

一 前言 本章節主要介紹OSI七層模型,TCP/IP四層模型劃分,以及日常使用的路由器,交換機的一些基礎知識 二 OSI 七層 OSI(Open Systems Interconnection Model)即開放式系統互聯模型,是國際標準化組織提出的&…

【JavaSE面試篇】Java集合部分高頻八股匯總

目錄 概念 1. 說說Java中的集合? 2. Java中的線程安全的集合有什么? 3. Collections和Collection的區別? 4. 集合遍歷的方法有哪些? List 5. 講一下java里面list的幾種實現,幾種實現有什么不同? 6.…

利用低空無人機影像進行樹種實例分割

在本項先導研究中,我們開發了一個基于低空無人機影像的本地樹種機器學習實例分割模型,用于生態調查。該實例分割包括單株樹冠的描繪和樹種的分類。我們利用無人機影像對20個樹種及其對應的學名進行了訓練,并收集了這些樹種的學名用于機器學習。為了評估該機器學習模型的準確…

二、Flutter基礎

目錄1. 什么是Widget?Flutter中的Widget分為哪幾類?2. StatelessWidget和StatefulWidget的區別3. StatefulWidget生命周期4. 什么是BuildContext?5. 如何優化Widget重建?6. Flutter布局機制7. Row/Column的主軸和交叉軸8. Expande…

設計模式筆記_創建型_建造者模式

1. 建造者模式介紹 建造者模式是一種創建型設計模式,旨在通過將復雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示。它通常用于構造步驟固定但具體實現可能變化的對象。 1.1 功能: 封裝復雜對象的創建過程:適…

【ROS2 自動駕駛學習】03-ROS2常用命令

目錄 1. ros2 pkg list 2. ros2 node list 3. ros2 node info 節點名稱 4. ros2 topic list 5. ros2 topic info 話題名 6. ros2 topic type 話題名 7. ros2 topic find 消息類型 8. ros2 service list 9. ros2 service type 服務名稱 10. ros2 service find 服…

MyBatis-Plus:提升數據庫操作效率的利器

在Java開發中,MyBatis是一個非常流行的持久層框架,它簡化了數據庫操作,提供了靈活的SQL映射功能。然而,隨著項目規模的擴大和業務復雜度的增加,開發者需要更高效、更便捷的方式來處理數據庫操作。MyBatis-Plus應運而生…

App爬蟲實戰篇-以華為真機手機爬取集換社的app為例

前言 在開始學習這篇文章之前,建議你先按照之前2篇文章(App爬蟲工具篇-Appium安裝和App爬蟲工具篇-appium配置),配置必要的環境,才可以繼續完成本章節內容。 電腦連接手機 可以通過usb連接電腦。如果通過adb devices命令,發現沒有連接上,就需要手動配置一些信息 華為…

Vue3組合式API應用:狀態共享與邏輯復用最佳實踐

Vue3組合式API應用:狀態共享與邏輯復用最佳實踐 在Vue3中,組合式API的引入為我們提供了一種全新的方式來編寫Vue組件,并有效地解決了混入和繁瑣邏輯復用的問題。本文將為您介紹如何在Vue3中使用組合式API來實現狀態共享與邏輯復用的最佳實踐&…

在linux 上使用tcpdump監聽http 端口的報文并分析

這里寫目錄標題 1. 使用 tcpdump(原始報文捕獲)觀察:報文翻譯與分析(按行解釋)第一段:客戶端請求報文HTTP 請求頭JSON 請求體第二段:服務器響應報文HTTP 響應頭響應體關鍵問題分析在 Linux 上監聽 HTTP 端口的報文,有多種工具可以實現。以下是幾種常用方法的詳細說明:…

XSStrike 進行 XSS 漏洞測試

XSStrike 是一個功能強大的 XSS 漏洞測試工具,專為檢測、驗證和利用反射型、存儲型、DOM型 XSS 漏洞而設計,適合配合手工測試,也可用于自動化發現。 🛠? 1. 安裝 XSStrike 確保系統中有 Python3 和 git: git clone ht…

any實現(基于LLVM中libcxx實現分析)

本文根據LLVM中libcxx的實現,分析了std::any和std::variant的具體實現。 1 簡介 在 C17 標準中,std::any提供了一種類型安全的方式來存儲任意類型的值。它使用類型擦除(type erasure)技術實現,使得一個對象可以包含任…

網安系列【13】之滲透測試:前期信息收集

文章目錄 前期信息收集信息收集的分類信息收集的內容域名信息收集Whois備案信息whois反查SSL證書查詢域名收集工具IP收集CDN信息收集CDN判斷CDN繞過 端口信息收集常見端口介紹FTP-21SSH-22WWW-80NetBlOSSessionService-139/445MySQL-3306RDP-3389Redis-6379Tomcat-8080 端口掃描…

自動駕駛傳感器的標定與數據融合

目錄 IMU的標定 相機的標定 激光雷達和組合慣導標定 相機和激光雷達標定 傳感器數據融合 多傳感器融合數據處理 傳感器數據融合算法 環境感知與預測 應用實例——車道線識別 應用實例——車輛行人識別 應用實例——交通標志識別 定位系統 基于慣性導航儀的定位技術…

27.移除元素(快慢指針)

給你一個數組 nums 和一個值 val,你需要 原地 移除所有數值等于 val 的元素。元素的順序可能發生改變。然后返回 nums 中與 val 不同的元素的數量。 假設 nums 中不等于 val 的元素數量為 k,要通過此題,您需要執行以下操作: 更改…

Spring AI:ETL Pipeline

提取、轉換和加載(ETL)框架是檢索增強生成(RAG)用例中數據處理的支柱。ETL管道協調從原始數據源到結構化向量存儲的流程,確保數據以最佳格式供AI模型檢索。RAG用例是文本,通過從數據體中檢索相關信息來增強…

26.安卓逆向2-frida hook技術-解密響應

免責聲明:內容僅供學習參考,請合法利用知識,禁止進行違法犯罪活動! 內容參考于:圖靈Python學院 工具下載: 鏈接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取碼&#xff1…

人工智能與人工智障———仙盟創夢IDE

<!-- 桌面導航 -->&#x3C;nav class&#x22;hidden md:flex items-center space-x-8&#x22;&#x3E;&#x3C;a href&#x22;#home&#x22; class&#x22;nav-link text-gray-700 hover:text-primary font-medium&#x22;&#x3E;&#x9996;&…