Is it bad to use code like:
var a = [1,2,3,4];
a.length = 2; // 3 and 4 are removed
Does it have decent browser support? Do the removed values get garbage collected properly?
We started with Q&A. Technical documentation is next, and we need your help.
Whether you're a beginner or an experienced developer, you can contribute.
Is it bad to use code like:
Does it have decent browser support? Do the removed values get garbage collected properly? |
|||||||||||||||||||||
|
Yes. This has been present since the very first edition of ECMAScript:
In ECMAScript 5, this was moved to 15.4.5.2.
All browsers support this behavior.
Yes. (See quotes above, and 15.4.5.1.)
No, not really. While arrays are "exotic objects" in ES6-speak, the real crazily unique thing about arrays are their indexing, not setting the It's true that property setters with non-subtle effects are somewhat unusual in JS, as their side-effects can be unobvious. But since If you want an alternative, use
If I were avoid setting
|
||||
|
Arrays are exotic objects.
The property semantics for arrays are special, in this case that changing length affects the actual contents of the array.
The behavior of the specific property key for this array exotic object is outlined as well.
This section is detailing that the length property is a 32 bit integer. It is also saying that if an array index is added, the length is changed. What this is implying is that when an own property name that is not an index is used, the length is not changed and also that names which are not indexes are considered numerically less than the indexes. This means that if you have an array and also add a string (not implicitly numeric either, as in not "3") property to it, that changing the length to delete elements will not remove the value associated with the string property. For example,
In addition to the truncation, expansion is also available by use of an index. If an index value is used (an integer basically) then the length will be updated to reflect that change. As arrays in JavaScript are sparse (as in, no gaps allowed) this means that adding a value for a larger index can make an array rather larger.
Finally, this is the specific aspect in question which the OP raises. When the length property of an array is modified, it will delete every index and value which is numerically more than the new length value minus 1. In the OP's example, we can clearly see that changing the length to 2 removed the values at index 2 and 3, leaving only the first two values who had index 0 and 1. The algorithm for the deletion mentioned above can be found in the ArraySetLength(A, Desc) definition.
Which is converting the index to a string and using the delete behavior for objects on the index. At which point the entire property is removed. As this internally reaches the delete call, there is no reason to believe that it will leak memory or even that it is an anti pattern as it is explicitly described in the language specification. In conclusion, Does it have decent browser support? Yes. Do the removed values get garbage collected properly? Yes. However, is it an anti-pattern? This could be argued either way. What it really breaks down to is the level of familiarity with the language of others who would be using the same code which is a nice way of saying that it may not have the best readability. On the other hand, since JavaScript does take up bandwidth or memory with each character used (hence the need for minification and bundling) it can be useful to take this approach to truncate an array. More often than not, worrying about this type of minutia is going to be a micro-optimization and the use of this special property should be considered on a case to case basis in context with the overall design of the related code. 1. The Object Type ECMA 6 |
|||||||||
|
As it is writeable https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length (seen here) It should be okay to use it that way
There's even an example how to shorten an array, using this on Mozilla Developer Network
|
|||||||||||||||||||||
|
It's better to use slice because your intentions are clear.
Slice does create a new array though. If that is an issue for you then there is nothing wrong with modifying the length property. It's actually the fastest way of truncation and supported in all browsers. jsperf |
|||||||||||||
|
No. It would be OK to set it to truncate the array.
Yes, see the compatiblity matrix here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length
Yes, they should. Will they actually get gced - you will need to profile the JavaScript code if this is a real concern. |
||||
|
This way of truncating an array is mentioned in JavaScript: Good Parts, so it is not an anti-pattern. |
|||||||||
|
It is not an anti pattern. It is supported in all major browsers. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length |
|||||
|