主頁 >  其他 > 比較JavaScript中的資料結構(陣列與物件)

比較JavaScript中的資料結構(陣列與物件)

2020-10-01 21:05:36 其他

作者:Vivek Bisht
譯者:前端小智
來源:blog
移動端閱讀:https://mp.weixin.qq.com/s/nbYsKonWtLNK95jMd4dY-A

點贊再看,微信搜索 【大遷世界】 關注這個沒有大廠背景,但有著一股向上積極心態人,本文 GitHub https://github.com/qq449245884/xiaozhi 上已經收錄,文章的已分類,也整理了很多我的檔案,和教程資料,

大家都說簡歷沒專案寫,我就幫大家找了一個專案,還附贈【搭建教程】,

在編程中,如果你想繼續深入,資料結構是我們必須要懂的一塊, 學習/理解資料結構的動機可能會有所不同,一方面可能是為了面試,一方面可能單單是為了提高自己的技能或者是專案需要,無論動機是什么,如果不知道什么是陣列結構及何時使用應用字們,那學資料結構是一項繁瑣且無趣的程序 😵

這篇文章討論了什么時候使用它們,在本文中,我們將學習陣列和物件,我們將嘗試通過使用Big O notation來理解何時選擇一種資料結構,

Big O notation 大零符號一般用于描述演算法的復雜程度,比如執行的時間或占用記憶體(磁盤)的空間等,特指最壞時的情形,

陣列

陣列是使用最廣泛的資料結構之一, 陣列中的資料以有序的方式進行結構化,即陣列中的第一個元素存盤在索引0中,第二個元素存盤在索引1中,依此類推, JavaScript為我們提供了一些內置的資料結構,陣列就是其中之一 👌

在JavaScript中,定義陣列最簡單的方法是:

let arr = []

上面的代碼行創建了一個動態陣列(長度未知),為了了解如何將陣列的元素存盤在記憶體中,我們來看一個示例:

let arr = ['John', 'Lily', 'William', 'Cindy']

在上面的示例中,我們創建一個包含一些人名的陣列, 記憶體中的名稱按以下方式存盤:

在這里插入圖片描述

為了理解陣列是如何作業的,我們需要執行一些操作:

添加元素:

在JavaScript陣列中,我們有不同方式在陣列結尾,開關以及特定索引處添加元素,

在陣列的末尾添加一個元素:

JavaScript 中的陣列有一個默認屬性 length,它表示陣列的長度,除了length屬性外,JS還提供了 push() 方法, 使用這個方法,我們可以直接在最后添加一個元素,

arr.push('Jake')

在這里插入圖片描述

那么這個命令的復雜度是多少呢?我們知道,在默認情況下,JS提供了length屬性,push()相當于使用以下命令:

arr[arr.length - 1] = 'Jake'

因為我們總是可以訪問陣列的長度屬性,所以無論陣列有多大,在末尾添加一個元素的復雜度總是O(1) 👏,

在陣列的開頭添加一個元素:

對于此操作,JavaScript提供了一個稱為unshift()的默認方法,此方法將元素添加到陣列的開頭,

let arr = ['John', 'Lily', 'William', 'Cindy']
arr.unshift('Robert')
console.log(arr) // [ 'Robert', 'John', 'Lily', 'William', 'Cindy' ]

unshift方法復雜度好像和push方法的復雜度一樣:O(1),因為我們只是在前面添加一個元素, 事實并非如此,讓我們看一下使用unshift方法時會發生什么:

在這里插入圖片描述

在上圖中,當我們使用unshift方法時,所有元素的索引應該增加1,這里我們的陣列個數比較少,看不出存在的問題,想象一下使用一個相當長的陣列,然后,使用unshift這樣的方法會導致延遲,因為我們必須移動陣列中每個元素的索引,因此,unshift操作的復雜度為O(n) 😋,

如果要處理較大長度的陣列,請明智地使用unshift方法,在特定索引處添加元素,我們可以 splice() 方法,它的語法如下:

splice(startingIndex, deleteCount, elementToBeInserted)

因為我們要添加一個元素,所以deleteCount將為0,例如, 我們想要在陣列索引為2的地方新加一個元素,可以這么用:

let arr = ['John', 'Lily', 'William', 'Cindy']
arr.splice(2, 0, 'Janice')
console.log(arr)
// [ 'John', 'Lily', 'Janice', 'William', 'Cindy' ]

你覺得這個操作的復雜性是多少?在上面的操作中,我們在索引2處添加了元素,因此,在索引2之后的所有后續元素都必須增加或移動1(包括之前在索引2處的元素),

在這里插入圖片描述

可以觀察到,我們不是在移動或遞增所有元素的索引,而是在索引2之后遞增元素的索引,這是否意味著該操作的復雜度為 `O(n/2)? 不是 😮, 根據Big O規則,常量可以從復雜性中洗掉,而且,我們應該考慮最壞的情況, 因此,該操作的復雜度為O(n) 😳,

洗掉元素:

就像添加元素一樣,洗掉元素可以在不同的位置完成,在末尾、開始和特定索引處,

在陣列的末尾洗掉一個元素:

push( )一樣,JavaScript提供了一個默認方法pop(),用于洗掉/洗掉陣列末尾的元素,

let arr = ['Janice', 'Gillian', 'Harvey', 'Tom']
arr.pop()
console.log(arr)
// [ 'Janice', 'Gillian', 'Harvey' ]

arr.pop()
console.log(arr)
// [ 'Janice', 'Gillian' ]

該操作的復雜度為O(1),因為,無論陣列有多大,洗掉最后一個元素都不需要改變陣列中任何元素的索引,

在陣列的開頭洗掉一個元素:

JavaScript 提供了一個默認方法shift() 的默認方法,此方法洗掉陣列的第一個元素,

let arr = ['John', 'Lily','William','Cindy']
arr.shift()
console.log(arr) // ['Lily','William','Cindy']
arr.shift()
console.log(arr);// ['William','Cindy'] 

在這里插入圖片描述

從上面我們很容易可以看出 shift()操作的復雜度為O(n) ,因為洗掉第一個元素后,我們必須將所有元素的索引移位或減量1

在特定索引處洗掉:

對于此操作,我們再次使用splice()方法,不過這一次,我們只使用前兩個引數,因為我們不打算在該索引處添加新元素,

let arr = ['Apple', 'Orange', 'Pear', 'Banana','Watermelon']
arr.splice(2,1)
console.log(arr) // ['Apple', 'Orange', 'Banana','Watermelon']

與用splice添加元素操作類似,在此操作中,我們將遞級訓移動索引2之后的元素索引,所以復雜度是O(n)

查找元素:

查找只是訪問陣列的一個元素,我們可以通過使用方括號符號(例如: arr[4])來訪問陣列的元素,

你認為這個操作的復雜性是什么? 我們通過一個例子來演示一下:

let fruits = ['Apple', 'Orange', 'Pear']

在這里插入圖片描述

前面我們已經看到,陣列的所有元素都按順序存盤,并且始終分組在一起, 因此,如果執行fruits1,它將告訴計算機找到名為fruits的陣列并獲取第二個元素(陣列從索引0開始),

由于它們是按順序存盤的,因此計算機不必查看整個記憶體即可找到該元素,因為所有元素按順序分組在一起,因此它可以直接在fruits陣列內部查看, 因此,陣列中的查找操作的復雜度為 O(1)

我們已經完成了對陣列的基本操作,我們先來小結一下什么時候可以使用陣列:

當你要執行像push()(在末尾添加元素)和pop()(從末尾洗掉元素)這樣的操作時,陣列是合適的,因為這些操作的復雜度是O(1)

除此之外,查找操作可以在陣列中非常快地執行,

使用陣列時,執行諸如在特定索引處或在開頭添加/洗掉元素之類的操作可能會非常慢,因為它們的復雜度為O(n)

物件

像陣列一樣,物件也是最常用的資料結構之一, 物件是一種哈希表,允許我們存盤鍵值對,而不是像在陣列中看到的那樣將值存盤在編號索引處,

定義物件的最簡單方法是:

let obj1 = {}

事例:

let student = {
    name: 'Vivek',
    age: 13,
    class: 8
}

來看一下上面的物件是如何存盤在記憶體中的:

在這里插入圖片描述

可以看到,物件的鍵-值對是隨機存盤的,不像陣列中所有元素都存盤在一起,這也是陣列與物件的主要區別,在物件中,鍵-值對隨機存盤在記憶體中,

我們還看到有一個哈希函式(hash function), 那么這個哈希函式做什么呢? 哈希函式從物件中獲取每個鍵,并生成一個哈希值,然后將此哈希值轉換為地址空間,在該地址空間中存盤鍵值對,

例如,如果我們向學生物件添加以下鍵值對:

student.rollNumber = 322

rollNumber鍵通過哈希函式,然后轉換為存盤鍵和值的地址空間,現在我們已經對物件如何存盤在記憶體有了基本的了解,讓我們來執行一些操作,

添加

對于物件,我們沒有單獨的方法將元素添加到前面或后面,因為所有的鍵-值對都是隨機存盤的,只有一個操作是向物件添加一個新的鍵值對,

事例:

student.parentName = 'Narendra Singh Bisht'

在這里插入圖片描述

從上圖中我們可以得出結論,這個操作的復雜性總是O(1),因為我們不需要改變任何索引或操作物件本身,我們可以直接添加一個鍵-值對,它被存盤在一個隨機的地址空間,

洗掉

與添加元素一樣,物件的洗掉操作非常簡單,復雜度為O(1),因為,我們不必在洗掉時更改或操作物件,

delete student.parentName

查找

查找的復雜度O(1) ,因為在這里,我們也只是借助鍵來訪問值,訪問物件中的值的一種方法:

student.class

在物件中添加,洗掉和查找的復雜度為O(1)???那么我們可以得出結論,我們應該每次都使用物件而不是陣列嗎? 答案是不, 盡管物件很棒,但是在使用物件時需要考慮一些小的情況,就是哈希碰撞(Hash Collisions), 在使用物件時,并非始終應處理此情況,但了解該情況有助于我們更好地理解物件,

那么什么是哈希碰撞?

當我們定義一個物件時,我們的計算機會在記憶體中為該物件分配一些空間, 我們需要記住,我們記憶體中的空間是有限的,因此有可能兩個或更多鍵值對可能具有相同的地址空間,這種情況稱為哈希碰撞, 為了更好地理解它,我們看一個例子:

假設為下面的物件分配了5塊空間

在這里插入圖片描述

我們觀察到兩個鍵值對存盤在相同的地址空間中, 怎么會這樣?當哈希函式回傳一個哈希值,該哈希值轉換為多個鍵的相同地址空間時,就會發生這種情況, 因此,多個 key 被映射到相同的地址空間, 由于哈希碰撞,添加和訪問物件值的復雜度為O(n) ,因為要訪問特定值,我們可能必須遍歷各種鍵值對,

哈希碰撞并不是我們每次使用物件時都需要處理的東西, 這只是一個特殊的情況,該情況也說明了物件不是完美的資料結構,

除了*哈希碰撞,使用物件時還必須注意另一種情況, JS 為我們提供了一個內置的keys()方法,用于遍歷物件的鍵,

我們可以將此方法應用于任何物件,例如:object1.keys()keys()方法遍歷物件并回傳所有鍵, 盡管此方法看起來很簡單,但我們需要了解物件中的鍵值對是隨機存盤在記憶體中的,因此,遍歷物件的程序變得較慢,這與遍歷按順序將它們分組在一起的陣列不同,

總結一下,當我們想執行諸如添加,洗掉和訪問元素之類的操作時,可以使用物件,但是在使用物件時,我們需要謹慎地遍歷物件,因為這可能很耗時, 除了進行遍歷外,我們還應該理解,有時由于哈希碰撞,訪問物件操作的復雜度可能會變為O(n)


代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug,

原文:https://blog.soshace.com/comparing-data-structures-in-javascript-arrays-vs-objects/

交流

文章每周持續更新,可以微信搜索 【大遷世界 】 第一時間閱讀,回復 【福利】 有多份前端視頻等著你,本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,歡迎Star,

前端小智@大遷世界 CSDN認證博客專家 TypeScript ECMAScript 6 前端框架
我不是什么大牛,我其實想做的就是一個傳播者,內容可能過于基礎,但對于剛入門的人來說或許是一個視窗,一個解惑之窗,我要先堅持分享20年,大家來一起見證吧,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/146354.html

標籤:AI

上一篇:一般公司網站的制作流程

下一篇:微信小程式 - wx.navigateTo({}) 跳轉頁面攜帶 物件/陣列/復雜資料 引數(攜帶一個復雜物件資料引數)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more