javascript
如何在 JavaScript 中清空数组?
問:
這個問題的答案是社區的努力。編輯現有答案以改進這篇文章。它目前不接受新的答案或交互。
有沒有辦法清空數組,如果可能的話,可以使用 .remove()?
例如,
A = [1,2,3,4];我怎樣才能清空它?
huntsbot.com洞察每一個產品背后的需求與收益,從而捕獲靈感
答1:
huntsbot.com – 高效賺錢,自由工作
清除現有數組 A 的方法:
方法一
(這是我對這個問題的原始答案)
A = [];此代碼會將變量 A 設置為一個新的空數組。如果您在其他任何地方都沒有對原始數組 A 的引用,這是完美的,因為這實際上創建了一個全新的(空)數組。您應該小心使用此方法,因為如果您從另一個變量或屬性引用了此數組,則原始數組將保持不變。僅當您僅通過原始變量 A 引用數組時才使用此選項。
這也是最快的解決方案。
此代碼示例顯示了使用此方法時可能遇到的問題:
var arr1 = ['a','b','c','d','e','f']; var arr2 = arr1; // Reference arr1 by another variable arr1 = []; console.log(arr2); // Output ['a','b','c','d','e','f']方法 2(作為 Matthew Crumley 的 suggested)
A.length = 0這將通過將其長度設置為 0 來清除現有數組。有人認為這可能不適用于 JavaScript 的所有實現,但事實證明并非如此。它在 ECMAScript 5 中使用“嚴格模式”時也有效,因為數組的長度屬性是一個讀/寫屬性。
方法 3(作為 Anthony 的 suggested)
A.splice(0,A.length)使用 .splice() 將完美運行,但由于 .splice() 函數將返回一個包含所有已刪除項目的數組,它實際上將返回原始數組的副本。基準表明這對性能沒有任何影響。
方法 4(作為 tanguy_k 的 suggested)
while(A.length > 0) {A.pop(); }這個解決方案不是很簡潔,也是最慢的解決方案,與原始答案中引用的早期基準相反。
表現
在清除現有數組的所有方法中,方法 2 和 3 的性能非常相似,并且比方法 4 快很多。請參閱此benchmark。
正如 Diadistis 在下面的 answer 中所指出的,用于確定上述四種方法的性能的原始基準存在缺陷。最初的基準測試重用了清除的數組,因此第二次迭代清除了一個已經為空的數組。
以下基準修復了此缺陷:http://jsben.ch/#/hyj65。它清楚地表明方法#2(長度屬性)和#3(拼接)是最快的(不計算方法#1,它不會改變原始數組)。
這一直是一個熱門話題,也引發了很多爭議。實際上有很多正確的答案,因為這個答案已經被標記為接受的答案很長時間了,我將在這里包括所有的方法。
while (A.length) { A.pop(); },不需要 > 0
> 0 恕我直言,更具可讀性。兩者之間沒有性能差異。
@daghan,完全不清楚您要說什么。即使在 a 被分配了一個新數組之后,b 也會保留對舊數組的引用。 c 和 d 繼續引用同一個數組。因此,預計會出現產出差異。
@DiegoJancic 方法 #1 不算數,因為它不會清除數組。它創造了一個新的。它不應該包含在基準測試中。
如果數組中的項目是假的,則不能使用 while(A.pop())。例如,A = [2, 1, 0, -1, -2] 將導致 A 等于 [2, 1]。甚至 while(A.pop() !== undefined) 也不起作用,因為您可以將未定義的數組作為值之一。可能是編譯器沒有優化它的原因。
答2:
一個優秀的自由職業者,應該有對需求敏感和精準需求捕獲的能力,而huntsbot.com提供了這個機會
如果您需要保留原始數組,因為您對它的其他引用也應該更新,您可以通過將其長度設置為零來清除它而不創建新數組:
A.length = 0;ECMAScript 5 標準對此有何評論?
@Pacerier:它仍然適用于 ES5。從第 15.4 節:“......每當更改長度屬性時,名稱為數組索引且值不小于新長度的每個屬性都會自動刪除”
@LosManos 即使在嚴格模式下, length 也是一個特殊屬性,但不是只讀的,所以它仍然可以工作。
@MattewCrumley 我做了一些測試,似乎 a.length = 0 不能有效地清除整個數組。 jsperf.com/length-equal-0-or-new-array 我認為,如果您有一個引用(并且您沒有添加要保留的額外屬性),最好創建新數組,并將舊數組留給垃圾收集器,以便在適當時運行。
@jollarvia ECMAScript 規范要求刪除新長度以上的元素,因此任何正確的實現都會使任何不可訪問的元素成為垃圾回收。這并不一定意味著他們會立即縮小實際陣列的存儲空間。具體來說,V8 僅在新長度小于原始長度的一半時才重新分配數組,但將長度設置為零實質上是在幕后重新分配新數組。
答3:
huntsbot.com高效搞錢,一站式跟進超10+任務平臺外包需求
這是保持相同數組(“可變”)的最快工作實現:
function clearArray(array) {while (array.length > 0) {array.pop();} }僅供參考,它不能簡化為 while (array.pop()):測試將失敗。
僅供參考 Map 和 Set 定義 clear(),將 clear() 也用于 Array 似乎是合乎邏輯的。
打字稿版本:
function clearArray(array: T[]) {while (array.length > 0) {array.pop();} }相應的測試:
describe('clearArray()', () => {test('clear regular array', () => {const array = [1, 2, 3, 4, 5];clearArray(array);expect(array.length).toEqual(0);expect(array[0]).toEqual(undefined);expect(array[4]).toEqual(undefined);});test('clear array that contains undefined and null', () => {const array = [1, undefined, 3, null, 5];clearArray(array);expect(array.length).toEqual(0);expect(array[0]).toEqual(undefined);expect(array[4]).toEqual(undefined);}); });這里更新的 jsPerf:http://jsperf.com/array-destroy/32 http://jsperf.com/array-destroy/152
jsPerf 離線。類似基準:https://jsben.ch/hyj65
TT您的答案是唯一正確且快速(同時)但“贊成票”少得多的答案。好吧,似乎人們喜歡很慢的漂亮解決方案:/
@naomik 但這是基本功能之一,默認情況下應該存在。
@thefourtheye 良好的性能解決方案,雖然我同意@naomik,但您不應該修改本機對象。說它應該在那里是題外話,問題是你正在修改 globals,這很糟糕。如果您將代碼提供給其他人使用,那么它應該沒有不可預見的副作用。想象一下,如果另一個庫也修改了 Array.prototype,并且它做了一些稍微不同的事情,那么整個代碼 [].clear() 都有些錯誤。調試起來不會很有趣。所以,一般信息是:不要修改全局變量。
@thefourtheye 不修改全局范圍的全部意義在于,您不會知道其他人的代碼是否已經(或將要)使用該名稱。我建議在本地范圍內使用一個函數。因此,在您的應用程序/庫的 IIFE 中,執行 function clear(arr) { while(arr.length) arr.pop(); },然后使用 clear(arr) 而不是 arr.clear() 清除數組。
事實證明,這種方法比 .splice() 和 .length=0 慢很多。基準不正確。請參閱我的更新答案。
答4:
與HuntsBot一起,探索全球自由職業機會–huntsbot.com
更跨瀏覽器友好和更優化的解決方案是使用 splice 方法清空數組 A 的內容,如下所示:
A.splice(0, A.length);
為什么這對跨瀏覽器更友好?哪些瀏覽器對 A.length 有問題?
@jm2 你所說的并不完全正確。它實際上修改了有問題的數組,隨后所有引用都會受到影響。在我的 jsFiddle 上查看測試:jsfiddle.net/shamasis/dG4PH
@alex 不,它沒有,splice 修改數組并返回已刪除的條目。首先閱讀文檔:developer.mozilla.org/en-US/docs/JavaScript/Reference/…
我們可以通過使用 comma operator: A.splice(0, A.length),0; 來防止返回結果數組。這將留下 0 的返回值,就像 A.length = 0; 一樣。結果數組仍然被創建,應該導致腳本運行速度變慢:(jsperf ~56% 慢)。瀏覽器實現會影響這一點,盡管我看不出為什么 splice 會比設置 length 更快。
我還發現只有 A.splice(0) 也可以。
答5:
huntsbot.com聚合了超過10+全球外包任務平臺的外包需求,尋找外包任務與機會變的簡單與高效。
現在有不少于 2739 票的答案具有誤導性和不正確性。
問題是:“如何清空現有數組?”例如 A = [1,2,3,4]。
說“A = [] 是答案”是無知且絕對不正確的。 [] == [] 是假的。這是因為這兩個陣列是兩個獨立的個體對象,具有自己的兩個身份,在數字世界中占據自己的空間,每個都獨立。
假設你媽媽讓你清空垃圾桶。
你不會帶來一個新的,就好像你已經完成了你被要求做的事情。
相反,您清空垃圾桶。
你不會用一個新的空罐子替換裝滿的罐子,也不會像 A = [1,2,3,4] 中那樣從裝滿罐子的標簽“A”并將其粘貼到新罐子上; A = [];
清空數組對象是最簡單的事情:
A.length = 0;這樣,“A”下面的罐子不僅是空的,而且干凈如新!
此外,在罐子空之前,您無需手動清除垃圾!你被要求在一個回合內完全清空現有的垃圾,在罐子變空之前不要撿垃圾,如: while(A.length > 0) { A.pop();也不是,把你的左手放在垃圾桶的底部,用你的右手在頂部握住它,以便能夠拉出它的內容,如: A.splice(0, A.length);
不,您被要求清空它:
A.length = 0;這是唯一正確清空給定 JavaScript 數組內容的代碼。
您建議的解決方案的唯一問題是垃圾仍然存在,只是您更改了布告欄說沒有垃圾。對舊數組的引用應該仍然存在。你能確定垃圾收集器在設置 .length = 0 時也會刪除對數組及其屬性的所有引用嗎?我認為它確實如此,但對我來說這很神奇。至少可以使用 .clear() 方法來避免混淆。
我從來沒有說過這個解決方案是錯誤的。問題是這整個線程是完全不必要的。超過 3000 票表明,試圖找出最好的方法應該使它成為 EMCA 破解頭開發人員添加這種方法的足夠有效的案例。沒有人應該去弄清楚它。有三 - 四種不同的方法來做到這一點。在某些基準測試中,長度解決方案比其他解決方案慢得多。此外,對于任何合理的開發人員來說,設置 .length = 0 的想法都不會令人滿意。
因為要完成它應該做的事情,必須刪除所有引用。 .length = 0 甚至不是一個方法調用,所以如果在它設置為 0 時采取了其他操作(在大多數瀏覽器中通過定義 setter 進行),我仍然認為它太神奇了,無法真正相信它會做它應該做的事情去做。
因此,我寧愿自己清除它。一個清晰的方法可以被原型化,但這很丑陋。我的觀點是,這個實現應該已經存在,因此超過 10 000 名開發人員不必花費數小時閱讀這個線程,而不是考慮所有其他花費更多時間進行基準測試的人。
我喜歡這個答案中與現實世界的隱喻。感人的!
答6:
huntsbot.com洞察每一個產品背后的需求與收益,從而捕獲靈感
性能測試:
http://jsperf.com/array-clear-methods/3
a = []; // 37% slower a.length = 0; // 89% slower a.splice(0, a.length) // 97% slower while (a.length > 0) {a.pop(); } // Fastest在不注意您的平臺的情況下添加百分比變化并沒有多大用處。在我的機器上,pop 在 Chrome 34 中只是稍微快一點,但實際上比最新 Firefox 中的 [] 慢。
在 Firefox 39.0 32 位 Windows NT 6.3 64 位上測試,a=[] 是最快的!
這個 Chrome 下的測試結果肯定有問題。彈出循環怎么能比其他 3 個解決方案快得多?
@chqrlie 不是。這是最慢的方法。基準測試有缺陷。
請刪除此答案,因為它是錯誤的,并鏈接到一個毫無意義的有缺陷的測試作為假證據。
答7:
huntsbot.com匯聚了國內外優秀的初創產品創意,可按收入、分類等篩選,希望這些產品與實踐經驗能給您帶來靈感。
您可以將其添加到您的 JavaScript 文件中以允許“清除”您的數組:
Array.prototype.clear = function() {this.splice(0, this.length); };然后你可以像這樣使用它:
var list = [1, 2, 3]; list.clear();或者,如果您想確保不會破壞某些東西:
if (!Array.prototype.clear) {Array.prototype.clear = function() {this.splice(0, this.length);}; }很多人認為你不應該修改原生對象(比如 Array),我傾向于同意。請謹慎決定如何處理。
@naomik 你能解釋一下你為什么不贊成這樣做嗎?
修改 Array 和 String 等 javascript 原始函數是“不受歡迎的”。您可能正在重載已經存在的函數并丟棄對象類。可能有一個晦澀的 JavaScript 引擎,它已經具有 clear() 并期望它以不同的方式運行。我只說小心行事。
對數組成員執行 foreach 會突然開始包含 clear 鍵的問題怎么樣?
作為參考:Why is extending native objects a bad practice?
答8:
與HuntsBot一起,探索全球自由職業機會–huntsbot.com
您可以輕松地為您創建一個函數,更改 length 甚至將其添加到 native Array 作為 remove() 函數以供重復使用。
想象一下你有這個數組:
var arr = [1, 2, 3, 4, 5]; //the array好的,只需運行以下命令:
arr.length = 0; //change the length結果是:
[] //result清空數組的簡單方法…
也使用循環,這不是必需的,但只是另一種方法:
/* could be arr.pop() or arr.splice(0) don't need to return as main array get changed */function remove(arr) {while(arr.length) {arr.shift(); } }您還可以考慮一些棘手的方法,例如:
arr.splice(0, arr.length); //[]因此,如果 arr 有 5 個項目,它將從 0 拼接 5 個項目,這意味著數組中不會保留任何內容。
還有其他方法,例如簡單地重新分配數組:
arr = []; //[]如果您查看 Array 函數,還有許多其他方法可以做到這一點,但最推薦的一種可能是更改長度。
正如我首先所說,您也可以原型 remove() 因為它是您問題的答案。您可以簡單地選擇上述方法之一并將其原型化為 JavaScript 中的 Array 對象,例如:
Array.prototype.remove = Array.prototype.remove || function() {this.splice(0, this.length); };您可以像這樣簡單地調用它來清空 javascript 應用程序中的任何數組:
arr.remove(); //[]arr.length = 0; //改變長度
答9:
huntsbot.com – 程序員副業首選,一站式外包任務、遠程工作、創意產品分享訂閱平臺。
關于 while;pop/shift 在答案和評論中的表現存在很多混淆和錯誤信息。 while/pop 解決方案(如預期的那樣)性能最差。實際發生的是,對于在循環中運行片段的每個示例,安裝程序只運行一次。例如:
var arr = [];for (var i = 0; i < 100; i++) { arr.push(Math.random()); }for (var j = 0; j < 1000; j++) {while (arr.length > 0) {arr.pop(); // this executes 100 times, not 100000} }我創建了一個可以正常工作的新測試:
http://jsperf.com/empty-javascript-array-redux
警告:即使在這個版本的測試中,您也看不到真正的區別,因為克隆數組占用了大部分測試時間。它仍然表明 splice 是清除數組的最快方法(不考慮 [],因為雖然它是最快的,但實際上并沒有清除現有數組)。
很好的一點!我將使用正確的基準測試結果更新原始答案。
我不敢相信沒有人發現該基準錯誤。擁有超過 50 萬次觀看,您會期望有人注意到它。偉大的工作迪亞蒂斯
答10:
huntsbot.com精選全球7大洲遠程工作機會,涵蓋各領域,幫助想要遠程工作的數字游民們能更精準、更高效的找到對方。
如果您正在使用
a = [];然后你將新的數組引用分配給 a,如果 a 中的引用已經分配給任何其他變量,那么它也不會清空該數組,因此垃圾收集器不會收集該內存。
例如。
var a=[1,2,3]; var b=a; a=[]; console.log(b);// It will print [1,2,3];或者
a.length = 0;當我們指定 a.length 時,我們只是重置數組的邊界,其余數組元素的內存將由垃圾收集器連接。
而不是這兩種解決方案更好。
a.splice(0,a.length)和
while(a.length > 0) {a.pop(); }根據 kenshou.html 之前的回答,第二種方法更快。
除了在 a.length 上出錯之外,我沒有看到這個新答案在線程中添加了什么?
@Bergi我只想關注關于數組的實際內存表示
您是否有任何消息來源可以確認在執行 a.length=0; 時哪些 JS 引擎將創建一個新數組?這些引擎將如何作用于 a.length=500; 和 a.length=4;?
我在大多數瀏覽器上都試過了,比如 IE、Firefox、Chrome,它正在創建新數組。如果將長度設置為大于 0,那么它將創建一個包含未定義元素的數組,即它只會保存一些內存位置。
var a = [1]; var b = a; a.length = 0; console.log(b) 打印 Array [ ],所以它看起來不像是在創建一個新數組。
答11:
打造屬于自己的副業,開啟自由職業之旅,從huntsbot.com開始!
Array.prototype.clear = function() {this.length = 0; };并稱之為:array.clear();
請不要鼓勵修改原生對象。
為什么人們有這種傾向去獲取已接受的答案并將其放入原型函數中?你真的在你的項目中這樣做嗎?您是否有一個龐大的原型庫,包含在每個項目中?
為什么不直接輸入 array.length = 0?
@naomik “請不要鼓勵修改原生對象。” ——我完全同意這一點,但僅僅重復這句話本身就會顯得傲慢。提出這樣一個解決方案的人可能沒有意識到后果,并且在他們身上放下這一行而不是提供簡短的解釋或鏈接并沒有傳達除“我們,比你聰明的人,告訴你不要這樣做,因為我們更了解”。
作為參考:Why is extending native objects a bad practice?
原文鏈接:https://www.huntsbot.com/qa/rDZ6/how-do-i-empty-an-array-in-javascript?lang=zh_CN&from=csdn
一個優秀的自由職業者,應該有對需求敏感和精準需求捕獲的能力,而huntsbot.com提供了這個機會
總結
以上是生活随笔為你收集整理的如何在 JavaScript 中清空数组?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SRM 624 Building Hei
- 下一篇: h5 苹果12 拍照上传图片自动刷新页面