最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript稀疏數(shù)組示例教程

 更新時(shí)間:2022年06月27日 09:46:59   作者:錯(cuò)碼匠  
這篇文章主要為大家介紹了JavaScript稀疏數(shù)組的使用示例教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近有空在看一本關(guān)于 JS 數(shù)據(jù)結(jié)構(gòu)和算法的書,里面有提到數(shù)組,卻對(duì)數(shù)組的基本概念輕輕帶過(guò),雖然用了 JS 很久但是一直忙于需求業(yè)務(wù)的實(shí)現(xiàn)從未停下好好回視一下這個(gè) 既熟悉又陌生的朋友,于是查閱了一些資料,尤其是密集數(shù)組和稀疏數(shù)組的區(qū)別,意猶未盡之下,寫了這篇文章,以便更好地幫助理解書中的要點(diǎn),稍顯淺顯,也有不足望各位提點(diǎn)。

什么是稀疏數(shù)組?

通常編程語(yǔ)言中(C、JAVA等)數(shù)組都是預(yù)先設(shè)定好長(zhǎng)度的,他們的內(nèi)存占用是固定的,內(nèi)存地址是連續(xù)不間斷、緊密相連的,我們稱之為密集數(shù)組,好比 JS 中類型化數(shù)組(TypedArray)的 ArrayBuffer,但我們這里著重要說(shuō)的是通過(guò) Array 創(chuàng)建的數(shù)組,它其實(shí)是個(gè)對(duì)象,當(dāng)我們通過(guò) new Array() 創(chuàng)建一個(gè)數(shù)組時(shí),它只是一個(gè)帶有 length 屬性的數(shù)組對(duì)象,我們可以像對(duì)象一樣去操作它的屬性:

let array = new Array(10)
// 下標(biāo)可以是任何的字符串,就像操作 Object 一樣
array.name = 'This is an Array.'
array['name'] = 'This is an Array.' // 等效 array.name

雖然可以像操作 Object 那樣為數(shù)組對(duì)象添加屬性,但是真正計(jì)入數(shù)組元素的只能是以整數(shù)類型的字符作為下標(biāo)去映射值的元素,同時(shí)會(huì)影響其長(zhǎng)度屬性 length,我們接上段代碼繼續(xù):

// 雖然之前賦上了一個(gè)新的屬性 name,但是其長(zhǎng)度仍然輸出10,而非11
console.log(array.length) // 10
// 用整數(shù)類型下標(biāo)定義一個(gè)數(shù)組元素才會(huì)計(jì)入數(shù)組長(zhǎng)度
array['0'] = 'first' // 下標(biāo)其實(shí)都是字符串
array[11] = 'eleventh' // 看起來(lái)這個(gè)下標(biāo)是一個(gè)數(shù)字,但是 JS 會(huì)自動(dòng)把它轉(zhuǎn)為字符
console.log(array.length) // 12

長(zhǎng)度屬性是可以手動(dòng)變更的:

array.length = 100
console.log(array.length) // 100

數(shù)組對(duì)象本身可能不占用太多內(nèi)存,它只是包含了映射關(guān)系和長(zhǎng)度,真正占用內(nèi)存的是元素所映射的目標(biāo),也就是“鍵值”中的“值”。在V8引擎里,JS 的數(shù)組得到進(jìn)一步的優(yōu)化,其中有個(gè)概念叫 Holey(有孔洞的),也就是那些沒(méi)有被指明映射關(guān)系的空間,他們不占用內(nèi)存。如上看到,作為一門動(dòng)態(tài)語(yǔ)言,我們隨時(shí)可以向這個(gè)數(shù)組對(duì)象里添加、修改元素映射,也能隨時(shí)改變其長(zhǎng)度 length。自然地,其元素所占的內(nèi)存地址也就無(wú)所謂固定連續(xù)了,我們稱這種數(shù)組為稀疏數(shù)組(Sparse Array)。

創(chuàng)建帶有孔洞的稀疏數(shù)組

  • 使用 Array 構(gòu)造函數(shù):
let sparse = new Array(100)
  • 通過(guò)字面量:
let sparse = []
// 用一個(gè)超過(guò)原始長(zhǎng)度的下標(biāo)為元素賦值,也就為該元素創(chuàng)建了一個(gè)映射關(guān)系,同時(shí)改變了該數(shù)組的長(zhǎng)度
sparse[99] = 'last'
console.log(sparse.length) // 100
// 用對(duì)象字面量書寫數(shù)組時(shí),允許元素留空
sparse = [, , ,] // 這就創(chuàng)建了長(zhǎng)度為3的空洞的數(shù)組
console.log(sparse.length) // 3
  • 手動(dòng)修改一個(gè)大于原數(shù)組長(zhǎng)度的 length 值:
let sparse = ['red', 'green', 'blue'] // 三個(gè)元素的數(shù)組
sparse.length = 100 // 此時(shí)長(zhǎng)度已是100,但有效元素仍然只有3個(gè)

刪除元素的映射

從數(shù)組中刪除某個(gè)元素可以使用 pop、shift、splice 方法,那如何解除元素與某個(gè)對(duì)象的映射關(guān)系呢?我們可以像操作對(duì)象一樣用 delete,它不會(huì)刪除映射目標(biāo),僅僅是將元素和目標(biāo)對(duì)象的關(guān)聯(lián)斷開,從而形成一個(gè)孔洞,所以也不會(huì)改變這個(gè)數(shù)組的 length。

let one = '壹'
let array = []
array[0] = one // 將數(shù)組的第一個(gè)元素指到對(duì)象 one,長(zhǎng)度變?yōu)?1
console.log(array, array.length) // ['壹'], 1
delete array[0] // 刪除數(shù)組第一個(gè)元素的映射關(guān)系
console.log(array) // [空]
console.log(array.length) // 因?yàn)橹皇莿h除了元素的映射,長(zhǎng)度并沒(méi)有改變,仍然輸出 1
console.log(one) // one 的值并不會(huì)刪除,仍然保留,輸出 '壹'

現(xiàn)象

我們說(shuō)到,JS 的數(shù)組本質(zhì)上是對(duì)象——由整數(shù)字符作為下標(biāo)與目標(biāo)值構(gòu)成映射關(guān)系的自帶長(zhǎng)度屬性的對(duì)象,長(zhǎng)度可以大于有效(已創(chuàng)建映射關(guān)系的)元素的個(gè)數(shù)。從映射狀態(tài)來(lái)看,完全映射的數(shù)組有著和傳統(tǒng)密集數(shù)組類似的表現(xiàn),而不完全映射的數(shù)組在生產(chǎn)中會(huì)有些特別,但又在情理之中。

  • 訪問(wèn)沒(méi)有映射關(guān)系的數(shù)組元素時(shí),相當(dāng)于一個(gè)申明了卻沒(méi)有定義值的變量,所以會(huì)輸出 undefined:
let sparse = new Array(10)
console.log(sparse[0]) // undefined
  • 不完全映射的數(shù)組,在用 map()、forEach() 等方法做遍歷時(shí),它們只會(huì)遍歷已有映射關(guān)系的元素:
// 此時(shí)數(shù)組元素的映射關(guān)系一個(gè)都沒(méi)有創(chuàng)建,所以 forEach 不會(huì)有任何輸出
sparse.forEach((value, i) => {
  console.log(i, value)
}) // nothing
// 根據(jù)下標(biāo)為最后一個(gè)元素賦值
sparse[sparse.length - 1] = 'tenth'
// 只會(huì)輸出已建立映射的元素 sparse[sparse.length-1] 的值 'tenth'
sparse.forEach((value, i) => {
  console.log(i, value)
}) // 9, tenth
  • 使用 for 語(yǔ)句也只是用數(shù)組的 length 值作為循環(huán)依據(jù),它不會(huì)主動(dòng)判斷當(dāng)前位置是否有映射值,所以當(dāng)循環(huán)體試圖通過(guò)下標(biāo)訪問(wèn)沒(méi)有映射關(guān)系的位置時(shí),會(huì)輸出 undefined:
for( let i = 0; i < sparse.length; i += 1){
  console.log(i, sparse[i])
}
  • 映射完全的數(shù)組,可以被所有常用數(shù)組方法遍歷:
let array = ['1', 'day', 'white', 'Jake', undefined, null, 0] // 一個(gè)完全映射的數(shù)組
// 輸出每個(gè)元素,包括null、undefined、0
array.forEach((value, i) => {
  console.log(i, value)
})
  • 在做 some()、every() 等操作時(shí),不完全映射的數(shù)組的表現(xiàn)是特殊的,但也在情理之中,這取決于這些方法的設(shè)計(jì),例如 some(),即便長(zhǎng)度大于0,但因?yàn)槠渲袥](méi)有任何建立映射的元素,所以,相當(dāng)于給一個(gè)空數(shù)組([])做操作:
let sparse = new Array(10)
// 由于還沒(méi)有建立映射關(guān)系,所以 some 的回調(diào)也沒(méi)有觸發(fā),于是得到的結(jié)果依然是 false
console.log(sparse.some(item => !item)) // false
// 在所有元素都被賦值后,用同樣的回調(diào),some 的結(jié)果發(fā)生了變化
sparse.fill(false) // 賦值
console.log(sparse.some(item => !item)) // true
  • 當(dāng)把長(zhǎng)度設(shè)成小于實(shí)際元素個(gè)數(shù)的值時(shí),會(huì)把超出長(zhǎng)度的元素從當(dāng)前數(shù)組中剔除:
let array = ['one', 'two', 'three']
array.length = 1
console.log(array) // ['one']

稀疏數(shù)組的快速映射(強(qiáng)制創(chuàng)建映射關(guān)系)

只是讓數(shù)組中的映射元素個(gè)數(shù)與長(zhǎng)度屬性相同,并不能改變其稀疏的特性:

let sparse = new Array(5)
// Array.apply
let array1 = Array.apply(null, sparse)
// Array.from方法
let array2 = Array.from(sparse)
// 解構(gòu)
let array3 = new Array(...sparse)
let array4 = [...sparse]
// 把所有元素映射為 undefined 了
array1.forEach((item, i) => {
  console.log(i, item) // 輸出 undefined × 5
})
……

總結(jié)

以上是對(duì) JS Array 數(shù)組的粗淺認(rèn)知,在 JS 這門動(dòng)態(tài)語(yǔ)言里,通過(guò) Array 所創(chuàng)建的數(shù)組無(wú)所謂疏密,因?yàn)樗鼈儽举|(zhì)上還是對(duì)象。在實(shí)際生產(chǎn)時(shí),對(duì)于數(shù)據(jù)集合的操作應(yīng)當(dāng)盡量保持映射完全,避免不合預(yù)期的意外,更多關(guān)于JavaScript稀疏數(shù)組教程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 在JavaScript中處理時(shí)間之getHours()方法的使用

    在JavaScript中處理時(shí)間之getHours()方法的使用

    這篇文章主要介紹了在JavaScript中處理時(shí)間之getHours()方法的使用,是JS入門學(xué)些中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06
  • 詳解JavaScript中shift()方法的使用

    詳解JavaScript中shift()方法的使用

    這篇文章主要介紹了詳解JavaScript中shift()方法的使用,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06
  • javascript中字符串的定義示例代碼

    javascript中字符串的定義示例代碼

    javascript中字符串如何定義,下面有個(gè)不錯(cuò)的示例,大家可以學(xué)習(xí)下
    2013-12-12
  • js導(dǎo)航菜單(自寫)簡(jiǎn)單大方

    js導(dǎo)航菜單(自寫)簡(jiǎn)單大方

    一個(gè)簡(jiǎn)單的多級(jí)下拉菜單菜單但是由于業(yè)務(wù)和樣式上的要求,為了簡(jiǎn)潔找了好多都不適合于是自己寫了一個(gè),曬出來(lái)與大家分享,感興趣的朋友可以參考下哈,希望可以幫助到你
    2013-03-03
  • 詳解javascript void(0)

    詳解javascript void(0)

    這篇文章主要介紹了javascript void關(guān)鍵字的相關(guān)資料,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • JavaScript中的document.referrer在各種瀏覽器測(cè)試結(jié)果

    JavaScript中的document.referrer在各種瀏覽器測(cè)試結(jié)果

    這篇文章主要介紹了JavaScript中的document.referrer在各種瀏覽器測(cè)試結(jié)果,包括在多種情況下每個(gè)瀏覽器能否用document.referrer取到值,非常珍貴的測(cè)試結(jié)果,需要的朋友可以參考下
    2014-07-07
  • 結(jié)合代碼圖文講解JavaScript中的作用域與作用域鏈

    結(jié)合代碼圖文講解JavaScript中的作用域與作用域鏈

    JavaScript雖然沒(méi)有類,但變量和一些函數(shù)卻同樣擁有局部作用域的制約,下面結(jié)合代碼圖文講解JavaScript中的作用域與作用域鏈:
    2016-07-07
  • 淺談javascript:兩種注釋,聲明變量,定義函數(shù)

    淺談javascript:兩種注釋,聲明變量,定義函數(shù)

    下面小編就為大家?guī)?lái)一篇淺談javascript:兩種注釋,聲明變量,定義函數(shù)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • JavaScript數(shù)值類型知識(shí)匯總

    JavaScript數(shù)值類型知識(shí)匯總

    這篇文章主要給大家介紹了關(guān)于JavaScript數(shù)值類型知識(shí)匯總的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用JavaScript具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 使用Script元素發(fā)送JSONP請(qǐng)求的方法

    使用Script元素發(fā)送JSONP請(qǐng)求的方法

    下面小編就為大家?guī)?lái)一篇使用Script元素發(fā)送JSONP請(qǐng)求的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06

最新評(píng)論

山阳县| 通榆县| 绥滨县| 洛宁县| 银川市| 定结县| 宿松县| 达日县| 鄂尔多斯市| 砚山县| 新绛县| 颍上县| 自治县| 定远县| 南康市| 福贡县| 任丘市| 闵行区| 平南县| 雷波县| 炉霍县| 甘洛县| 博罗县| 茶陵县| 宁陵县| 盐源县| 利津县| 宜兴市| 沽源县| 林西县| 新田县| 惠安县| 喀什市| 昂仁县| 兰西县| 吐鲁番市| 大埔县| 辽源市| 教育| 涪陵区| 德州市|