走進javascript——數組的那些事

来源:http://www.cnblogs.com/pssp/archive/2017/05/25/6902031.html
-Advertisement-
Play Games

Array構造器 如果參數只有一個並且是Number類型,那麼就是指定數組的長度,但不能是NaN,如果是多個會被當做參數列表。 註意當只傳遞一個參數時,它只是指定該數組的長度,並不會去填充內容 由於傳遞一個參數時不會填充數組內容,因此forEach不會迴圈這些空內容,或者說forEach不是根據數組 ...


Array構造器

如果參數只有一個並且是Number類型,那麼就是指定數組的長度,但不能是NaN,如果是多個會被當做參數列表。

new Array(12)
// (12) [undefined × 12]
new Array('')
// [""]
new Array({})
// [Object]
new Array([])
// [Array(0)]
new Array(null)
// [null]
new Array(NaN)
// Uncaught RangeError: Invalid array length (無效的數組長度,因為NaN是Number類型,但又不是一個具體的數字因此報錯)

註意當只傳遞一個參數時,它只是指定該數組的長度,並不會去填充內容

由於傳遞一個參數時不會填充數組內容,因此forEach不會迴圈這些空內容,或者說forEach不是根據數組長度來迴圈的,以下代碼就不會被輸出任何內容

new Array(6).forEach(function(item,index){
  console.log(index)
});

像我們自己模擬的forEach基本上都是有問題的,因為我看大部分人都是通過for迴圈數組的長度來模擬的forEach

function forEach(arr,fun){
    for(var i = 0; i < arr.length; i++){
        fun(arr[i]);
    }
}

這就說明在某些情況下數組的長度是不可靠的,並且我們沒有辦法去真實的模擬forEach,通過判斷是不是undefined也是不准確的。

由於傳遞一個參數時只會增加數組長度而不會填充內容,因此我們可以利用這個特點來實現自定義索引起始位置。

new Array(10).concat([1,2,3,4,5]).forEach(function(item,index){
    console.log(`item: ${item} index: ${index}`);
});
// item: 1 index: 10
// item: 2 index: 11
// item: 3 index: 12
// item: 4 index: 13
// item: 5 index: 14

當然我們也可以這樣玩

new Array(10).concat([1,2,3,4,5]).concat(new Array(5)).concat([6,7,8,9,10])

這種方式有個好處就是,空內容不會被迴圈到。

它還可以用來實現相同的連續字元

new Array(5+1).join("哈") //由於數組索引是從0開始的所以需要加+1才是5
// "哈哈哈哈哈"

我們用它來輸出一個好玩的

new Array(3).concat(['l','o','v','e']).concat(new Array(3)).join('--')
// "------l--o--v--e------"

如果你希望設置預設填充內容可以使用數組的fill方法

new Array(5).fill(999)
[999, 999, 999, 999, 999]

我們也可以使用下麵這種方式來實現預設填充內容

var arr = new Array(5).join('5,').split(',');
arr.splice(-1,1);
// ["5", "5", "5", "5"]

以上這種方式的缺點就是都會變成字元串。

通過Array()方法來創建數組和用new方法來創建效果一樣。

數組的訪問

數組通過下標訪問

[2,3,4,5][1]
// 3

當我們通過以下方式進行訪問時,會被解析成連續運算返回最後一個值

[2,3,4,5][1,2]
// 4

由於以上[1,2]是去訪問數組的下標因而被解析成了1,2結果返回的是2,所以以上輸出4

數組也是一種特殊的對象,因此我們也可以通過鍵值對的形式去訪問

var arr = [];
arr.say = 'Hello';
arr.say
// "Hello"

數組與其他值的運算

數組和任何值相加都會將數組轉換成字元串再進行拼接

[1,2,3] + 6
// "1,2,36"
[1,2,3] + {}
// "1,2,3[object Object]"
[1,2,3] + [1,2,3]
// "1,2,31,2,3"

如果數組只有一個值,那麼當這個數組和其他值相減相乘等時會被轉換為數字,如果為空會被轉換為0

[5] - 2
// 3

如果是多個值,肯定是NaN

遍曆數組

使用for

var arr = [2,3,4,5];
for(let i = 0, len = arr.length; i < len; i++){
    console.log(arr[i])
}
// 2
// 3
// 4
// 5

使用forEach

var arr = [2,3,4,5];
arr.forEach((item)=>console.log(item))
// 2
// 3
// 4
// 5

使用map、filter、some等方法都可以達到遍曆數組的目的,不過這些方法都不能直接通過return來跳出迴圈,但我們可以通過以下方式來實現跳出迴圈

var arr = [2,3];
try{
    arr.forEach(function(item){
        if(item === 3){
            throw Error();
        }
        console.log(item);
    });
}catch(e){
}
// 2

使用for in

var arr = [2,3];
for(let k in arr){
    console.log(arr[k]);
}
// 2
// 3

不過由於for in會將繼承的屬性和方法也遍歷出來,如下所示

Array.prototype.a = 123;
Array.prototype.foo = function(){};
var arr = [2,3];
for(let k in arr){
    console.log(arr[k]);
}
// 2
// 3
// 123
// function (){}

所以我們還得過濾一下

Array.prototype.a = 123;
Array.prototype.foo = function(){};
var arr = [2,3];
for(let k in arr){
    if(arr.hasOwnProperty(k)){
        console.log(arr[k]);
    }
}
// 2
// 3

我們還可以使用for of來實現同樣的效果,並且沒有以上問題

var arr = [2,3];
for(let item of arr){
    console.log(item)
}
// 2
// 3

有時我們並不希望一次性遍歷所有的數組項,而是根據需求來執行,此時我們就需要用到迭代器了,數組中有一個keys方法可以生成一個迭代器,如下

var arr = [2,3];
var iterator = arr.keys();
console.log(iterator.next().value);
console.log('-----');
console.log(iterator.next().value);

// 0
// -----
// 1

返回的是索引 Array.prototype.keys

其他

實際上JavaScript中的數組並非是傳統意義上的數組,而是一個關聯數組,索引數組只是個錶面現象,我們通過下標的方式去訪問數組,它最終還是會被轉換為字元串的。

[2,3][1]
// 3

其實它是這樣

[2,3]["1"]
// 3

如果說javascript中的數組不是索引數組而是關聯數組,那麼我們在使用for迴圈時為什麼可以按照順序來輸出呢?

var arr = [2,3];
for(var i = 0, len = arr.length; i < len; i++){
    console.log(arr[i]);
}
// 2
// 3

如果我們仔細觀察以上代碼,會發現一個啃爹的現象,我們被欺騙了很久,我們是用0 1 2這樣的形式去訪問的數組,自然是按照順序輸出了,再看看下麵這段代碼,估計你就懂了

var arr = [2,3];
console.log(arr[0]);
console.log(arr[1]);
// 2
// 3

你可是手動去訪問人家某個具體屬性的,你說能不是按照順序輸出嗎。

這也就是為什麼數組可以使用for in方法來迴圈的原因,因為本質上來講數組具有對象的某些特性,也就說其實我們也可以自己用對象來模擬實現數組,不過我們需要手動去維護length屬性,從另外一個角度上來講JavaScript中的數組很大一部分只是維護了length屬性,跟對象沒什麼兩樣。


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

-Advertisement-
Play Games
更多相關文章
  • 在大型項目編碼推進中,涉及到 XML 解析問題時,大多數程式員都不太會選用底層的解析方式直接編碼。 主要存在編碼複雜性、難擴展、難復用....,但如果你是 super 程式員或是一個人的項目,也不妨一試。 Jdom/Dom4j/Xstream... 基於底層解析方式重新組織封裝的開源類庫,簡潔明瞭的 ...
  • 本節探討Java中的類載入機制,利用自定義的ClassLoader實現熱部署 ...
  • Myeclipse2016安裝Aptana 想裝個Aptana,裝了半天,網上說的什麼links方式啊,線上方式啊,都是什麼的浮雲。 所以自己來寫個安裝教程。 一、Aptana簡要介紹 Aptana有JavaScript,JavaScript函數,HTML,CSS語言的Code Assist功能。 ...
  • CNN神經網路架構至少包含一個捲積層 (tf.nn.conv2d)。單層CNN檢測邊緣。圖像識別分類,使用不同層類型支持捲積層,減少過擬合,加速訓練過程,降低記憶體占用率。 TensorFlow加速所有不同類弄捲積層捲積運算。tf.nn.depthwise_conv2d,一個捲積層輸出邊接到另一個捲積 ...
  • 1 導入jar包 1.1 導入Spring的開發包 1.2 導入mybatis的jar包 1.3 導入MySQL的驅動 1.4 導入mybatis與Spring的整合包 1.5 導入junit4.jar包 1.6 導入log4j.jar 1.5 導入c3p0.jar 1.6 導入spring-tes ...
  • 使用CI框架開發了一段時間,發現它容易上手,使用起來也方便,最重要是很輕便,這引起我的興趣去分析該框架的設計。這是國外開源的項目,有一段時間特別火,下麵讓我們來看看唄。 ...
  • 硬體環境: CPU:AMD Phenom(tm) II X4 955 Processor Memory:8G SSD(128G):/ HDD(1T):/home/ 軟體環境: OS:Ubuntu14.04.3 LTS Java:JDK1.7 關於ReentrantLock中非公平鎖和公平鎖詳細區別以 ...
  • object對象中的 public boolean equals(Object obj),對於任何非空引用值 x 和 y,當且僅當 x 和 y 引用同一個對象時,此方法才返回 true;註意:當此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,該協定聲... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...