标签云

微信群

扫码加入我们

WeChat QR Code

我怎么空在JavaScript数组?

Is there a way to empty an array and if so possibly with .remove()?

For instance,

A = [1,2,3,4];

How can I empty that?


here a benchmark with different possibilities: jsben.ch/#/7QyI1

2018年06月19日57分27秒

while (A.length) { A.pop(); }, no need for > 0

2018年06月18日57分27秒

> 0 is more readable IMHO. And there's no performance difference between the two.

2018年06月18日57分27秒

daghan, it's not at all clear what you're trying to say. b holds a reference to the old array even after a is assigned a new one. c and d continue to reference the same array. The difference in outputs is therefore expected.

2018年06月18日57分27秒

DiegoJancic Method #1 doesn't count because it doesn't clear the array. It creates a new one. It shouldn't be included in a benchmark.

2018年06月18日57分27秒

You can't use while(A.pop()) in case an item in the array is falsey. Take for example A = [2, 1, 0, -1, -2] would result in A equaling [2, 1]. Even while(A.pop() !== undefined) doesn't work because you can have an array with undefined as one of the values. Probably why the compiler doesn't optimized it.

2018年06月18日57分27秒

Acorn Yes, it will work in all browsers.

2018年06月19日57分27秒

what does ECMAScript 5 Standard says about this?

2018年06月19日57分27秒

Pacerier: It still works in ES5. From section 15.4: "...whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted"

2018年06月19日57分27秒

LosManos Even in strict mode, length is a special property, but not read only, so it will still work.

2018年06月18日57分27秒

MattewCrumley I done some test, and it seems like a.length = 0 is not to efficient clearing whole array. jsperf.com/length-equal-0-or-new-array I think if you have one refence (and you haven't added extra properties that you want to keep), it is better to create new array, and leaves old to the garbage collector, that will run when appropriate.

2018年06月19日57分27秒

TT your answer is the only one that correct and fast ( at the same time ) but have some much less "upvotes". Well, it seems that people like pretty solutions that are slow :/

2018年06月19日57分27秒

naomik But this is one of the basic functionalities, which should have been there by default.

2018年06月18日57分27秒

thefourtheye Good solution for performance, though I agree with naomik, you should not modify native objects. Saying that it should be there is beside the point, the problem is you're modifying globals, which is bad. If you're providing your code for others to use, then it should have no unforeseen side effects. Imagine if another library also modified the Array.prototype and it was doing something slightly different, then all throughout your code [].clear() was slightly wrong. This would not be fun to debug. So, the general message is: Don't modify globals.

2018年06月19日57分27秒

thefourtheye The whole point of not modifying global scope is because you won't know if someone else's code is already (or will be) using the name. I suggest a function inside local scope. So, inside your application's/library's IIFE, do function clear(arr) { while(arr.length) arr.pop(); }, then clear arrays with clear(arr) instead of arr.clear().

2018年06月19日57分27秒

It turns out this method is a lot slower than .splice() and .length=0. The benchmarks were not correct. See my updated answer.

2018年06月19日57分27秒

Why is this more cross-browser friendly? What browsers have issues with A.length?

2018年06月18日57分27秒

jm2 what you are saying is not entirely true. It actually modifies the array in question and subsequently all references get affected. See the test on my jsFiddle: jsfiddle.net/shamasis/dG4PH

2018年06月18日57分27秒

alex no it does not, splice modifies the array and returns the deleted entries. Read the docs first: developer.mozilla.org/en-US/docs/JavaScript/Reference/…

2018年06月19日57分27秒

We could prevent the resulting array from being returned by using the comma operator: A.splice(0, A.length),0;. This would leave a return value of 0 just as A.length = 0; would. The resulting array is still created and should cause the script to run slower: (jsperf ~56% slower). Browser implementation will affect this although I see no reason why splice would be faster than setting length.

2018年06月19日57分27秒

I have also found that just A.splice(0) also works.

2018年06月19日57分27秒

Adding the percentage changes arent much use without also noting your platform. On my machine pop is only very mildly quicker in Chrome 34 but actually slower than [] in latest Firefox.

2018年06月18日57分27秒

Testing in Firefox 39.0 32-bit on Windows NT 6.3 64-bit, the a=[] is fastest !

2018年06月19日57分27秒

There is definitely something fishy in this test result under Chrome. How in hell can the popping loop be that much faster then the other 3 solutions?

2018年06月19日57分27秒

chqrlie It's not. It's the slowest method. The benchmark test is flawed.

2018年06月19日57分27秒

Please delete this answer as it is wrong, and links to a meaningless flawed test as fake evidence.

2018年06月19日57分27秒

The only problem with your suggested solution is that the trash still exists, it is just that you changed the notice board saying that there is no trash. A reference to the old array should still exist. Can you be sure the garbage collector when setting .length = 0, will also remove all references to the array and its properties ? I think it does though, but to me that is magic. A .clear() method is desirable to avoid confusion to say the least.

2018年06月18日57分27秒

I never stated that this solution is wrong. The problem is that this entire thread is completely unncessary. Over 3000 votes shows that trying to figure out what the best way is should make it a valid enough case for the EMCA crack head developers to add such a method. Nobody should have to go through figuring it out. There are three - four different ways to do it. In some benchmarks, the length solutions is much slower than others. Furthermore, the idea of setting .length = 0, for any reasonable developer would not be a satisfactory one.

2018年06月19日57分27秒

Because to accomplish what it should, all references must be removed. .length = 0 is not even a method call, so if there is other actions taken when it is set to 0 ( which there is in most browsers through define setter ) I would still consider it too magical to actually trust it does what it supposed to do.

2018年06月19日57分27秒

Therefore, I'd rather clear it myself. A clear method can be prototyped but that is just ugly. My point is that this implementation should already be present so that over 10 000 developers didn't have to spend hours reading just this thread, not considering all others who spent more time benchmarking.

2018年06月19日57分27秒

there's only one way to empty your array fill it with new incoming data and discard it again. All others are either not, or are ridiculously inefficient and unforgivably cpu hungry. The only practical alternative is the A(n) = A.splice( 0, A.length ); in case you need to backup your previous content. p.s. Array.length is a read-write property \ method in case you've missed that basic fact. Meaning, you can expand it to a new length, you cant trim it to whichever length you'd want, and among others you can discard all members by shortening its length to 0. It's a Swiss-knife of the array.

2018年06月19日57分27秒

naomik Can you explain your reasoning why doing such a thing is frowned upon?

2018年06月18日57分27秒

It is "frowned upon" to modify javascript primitive functions like Array and String. You could possibly be overloading an already existing function and trash the object class. There might be an obscure javascript engine that already has clear() and expects it to behave a different way. Tread carefully is all I say.

2018年06月18日57分27秒

How about the problem where doing a foreach over the members of an array will suddenly start including a clear key?

2018年06月18日57分27秒

As a reference: Why is extending native objects a bad practice?

2018年06月19日57分27秒

Please don't encourage modification of the native objects.

2018年06月19日57分27秒

why do people have this tendency to grab the accepted answer and put it into a prototype function? Do you actually do this in your projects? Do you have a huge library of prototype additions that you include in every project?

2018年06月18日57分27秒

Why not just type array.length = 0?

2018年06月18日57分27秒

naomik "Please don't encourage modification of the native objects." -- I completely agree with this, but just repeating the sentence by itself comes across as arrogant. Someone proposing such a solution is likely not aware of the consequences, and dropping this line on them instead of providing a short explanation or a link does not convey a meaning other than "we, people smarter than you, tell you not to do this, because we know better".

2018年06月18日57分27秒

As a reference: Why is extending native objects a bad practice?

2018年06月19日57分27秒

Very good point! I'll update the original answer with the correct benchmark results.

2018年06月19日57分27秒

I can't believe nobody spotted that benchmark error. With over half a million views you would expect someone to notice it. Great work Diadistis

2018年06月19日57分27秒

No you've just swapped a named array container with a newly created anonymous one. `var A = [1,2,3,4]; var B; B = A.splice(0); console.log(A); console.log(B); '

2018年06月19日57分27秒

Apart from being wrong on a.length, I don't see what this new answer adds to the thread?

2018年06月19日57分27秒

Bergi I just want to focus about actual memory representation about array

2018年06月18日57分27秒

Do you have any source to confirm which JS engines will create a new array when a.length=0; is performed? How would those engines act for a.length=500; and a.length=4;?

2018年06月19日57分27秒

I tried it on most of browsers, like IE, Firefox, Chrome, it is creating new array. If you set length greater than 0 then it will create an array with undefined elements, i.e. it will just hold some memory locations.

2018年06月19日57分27秒

var a = [1]; var b = a; a.length = 0; console.log(b) prints Array [ ], so it doesn't seem like it's creating a new array to me.

2018年06月18日57分27秒

Why would you want to do such thing? Why add two more variables and a bunch of code to do the same thing?

2018年06月18日57分27秒

It could be a good answer to a different question: "How to convert all elements in an array to undefined elements".

2018年06月19日57分27秒

"length : Pops till length of an array is of Specified Size." Who told you this nonsense?

2018年06月19日57分27秒

BekimBacaj In essence, it does the same effect. It should probably have said length = ? instead of just length.

2018年06月18日57分27秒

BekimBacaj i have updated my answer, I just assumed that length pops till length, but i corrected now that length just truncates or increases the size of an array.

2018年06月18日57分27秒

This is irrelevant and not even JavaScript.

2018年06月19日57分27秒