Day 10
好好的吃頓飯也是一種優雅。刪除也是。
「如何把陣列或元素清空」也要寫一篇? 妳當牛肉麵在寫嗎?
自從有了這本「JavaScript 大全」當枕頭,阿不是,才發現自己真是懵懂無知,但求知識不嫌遲,只能盡量腦補,讓自己盡量處於知道 JavaScript 到底做了什麼的狀態~結論是:路,還很長。
原本以為 Javascript 像某些語言ㄧ樣,可以控制記憶體或把某部分的記憶體釋放出來,就在網路上開始找如何刪除變數的文章,結果搜尋結果清一色是在講,如何「刪除陣列裡的元素」這件事,才發現 JavaScript 似乎沒有完全把變數刪除這件事,我們也看不見記憶體的存取或清空的狀態,只能用一些機制來驗證。結論是對陣列 Array 來說,沒有把陣列刪除變數這件事,似乎就只能把陣列清空,而不能刪除變數。 自己無法作主的人生
用 Delete 刪除陣列可以嗎?
在「JavaScript 大全」裡 p55 有說明: 1.如果用let
來宣告變數,創立的特性會是nonconfigurable
也就是不可配置的,這個變數是不可用delete
這個運算子刪除。 2.如果不是在strict
模式底下,將值指定給一個為宣告的變數,JavaScript 會自動為我們創建一個全域變數,用這種方式創建的變數具有configurable
特性,也就是可以被delete
運算子刪除。
第一點說的宣告,其實也包括了用let
和const
來宣告變數,我們可以可以用簡單的方式來測試一下:
1 | let a = 42; |
變數 d
就真的這樣被刪除掉了!
那麼其他不是透過Delete
刪除的變數,是怎麼被全域環境清除掉的?
JavaScript 有一種清理 廚餘的機制,是一種垃圾收集器(garbage collector),它會在變數不再被使用的時候出現,並釋放掉不再使用的記憶體,當然,變數也就這樣真的刪除掉了。
終於要進入今天的主題了:刪除陣列元素 在拖什麼啊
完全清空陣列
第一種方法 全部掏掉
將空陣列[]直接指派給要清除的 Array,這種方式其實不算清空,比較像是我們拿另一塊空的記憶體,重新指派給這個變數。
1 | let arr1 = [1, 2, 3, 4, 5, 6]; |
可以確定的是,如果我們複製了一份,複製的那份將不會受到原陣列的影響。
這一種方式和底下幾種清除陣列元素的方式,有一個很大的不同,就是使用重新指派的方式清空陣列,如arr1 =[]
,因為重新指派,所以即使在這之前有做陣列複製如arr2 = arr1
,兩個陣列也不會互相影響。
第二種方法 將長度歸零就沒事?
直接將陣列的長度length
歸0
,這種方式效能會比較好。但是,恩湯恩湯。因為複製於這個陣列的其他陣列,也會被改變。也就是說是以參考同一個記憶體位置by Reference
的方式進行複製。
1 | let arr1 = [1, 2, 3, 4, 5, 6]; |
第三種 用 splice 就比較好?
splice()通常是拿來刪除陣列裡的某個元素,當然也可以拿來刪除元素,但是 splice()本身並不會複製一份新陣列,而是會指向原陣列的位址,所以原陣列被刪除的元素,複製過來的陣列元素也同時會被刪除。
splice()的用法在後面的篇章會有更詳盡的介紹。
1 | let arr1 = [1, 2, 3, 4, 5, 6]; |
第四種 趕盡殺絕的清
利用while
迴圈與陣列長度,使用pop()
從尾端刪除陣列元素的功能遍歷陣列,一一從尾端清除陣列元素,pop()
同樣是就地改變的方法,所以也會同時改動到被複製出來的陣列。我們在前幾章有講到控制陣列長度的特有屬性:Length,有興趣的可以參考一下。
1 | let arr1 = [1, 2, 3, 4, 5, 6]; |
以上三種方法,都是在複製陣列時,以參考同一個記憶體位置by Reference
的方式進行複製,所以使用arr1.length = 0
的方式清空陣列,則所複製出來的陣列arr2 = arr1
的arr2
會受原來的arr1
影響,同時被清空,所以將arr1.length = 0
也等於將arr2
清空。
Delete 的另一種用法:將陣列某一元素清除
Delete 的假清除 洞還在
在文章最初,我們介紹了用delete
運算子來刪除整個陣列,但其實它比較常被拿來清除陣列的某一元素。直接清除陣列元素的方法delete
,個人覺得這也不算真的清除,只是把這個元素回歸為空的狀態,也就是 empty(undefined)。我們可以以length
來驗證陣列元素並不會因為使用delete
而改變長度。
1 | let arr1 = [1, 2, 3, 4, 5]; |
刪除陣列的元素,類似將undefined
指定給該元素,但仍和empty
會有些微差距嘛?這點還需要驗證。要特別注意的是,用delete
刪元素並不會改變陣列的長度,且此陣列就成為一個「稀疏」的陣列。
使用「稀疏」陣列會造成什麼影響?有時候我們希望用一些方法來處理陣列,然後把處理完的結果回傳回來,如果陣列裡有稀疏的狀態,那麼當我麼用方法去遍歷陣列元素時,就會回傳 undefined
。
1 | let arr1 = [1, 2, 3, 4, 5]; |
把無所事事的傢伙通通踢出去
有時候我們會拿到有許多無效 被搞爛的元素在陣列裡,如何刪除陣列裡這些無所事事的undefined
、null
、0
或其他的元素?讓處理陣列資料時更順利?我們可以利用 JavaScript 的while
迴圈,來遍歷陣列內容,一一來把我們過濾過後,要保留的元素留在陣列中。
1 | function filter_array(testArray) { |
相信大家在看完這一篇之後,會對於刪除陣列或元素有更加深的認識。老實說,真心覺得鐵人賽最大的收穫,是在寫文章的時候,找到的資料有吸收,且發現原來這麼多方法與面向,真的是一件很有趣的事啊! 且前幾天收到一些大大的回饋,無論是指定或提問,都讓本人雀躍不已,在每一次的交流中,更可以加深自己對 JavaScript 的理解,實在感謝!
如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~