Is it an antipattern to set an array length in JavaScript?

前端 未结 7 825
广开言路
广开言路 2020-12-08 13:18

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 val

相关标签:
7条回答
  • 2020-12-08 13:44

    This way of truncating an array is mentioned in JavaScript: Good Parts, so it is not an anti-pattern.

    0 讨论(0)
  • 2020-12-08 13:45

    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

    You can set the length property to truncate an array at any time. When you extend an array by changing its length property, the number of actual elements does not increase; for example, if you set length to 3 when it is currently 2, the array still contains only 2 elements.

    There's even an example how to shorten an array, using this on Mozilla Developer Network

    if (statesUS.length > 50) {
        statesUS.length = 50;
    }
    
    0 讨论(0)
  • 2020-12-08 13:46

    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

    0 讨论(0)
  • 2020-12-08 13:50

    Does it have decent browser support?

    Yes. This has been present since the very first edition of ECMAScript:

    Specifically, whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index; and 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.

    Standard ECMA-262, 15.4

    In ECMAScript 5, this was moved to 15.4.5.2.

    Attempting to set the length property of an Array object to a value that is numerically less than or equal to the largest numeric property name of an existing array indexed non-deletable property of the array will result in the length being set to a numeric value that is one greater than that largest numeric property name.

    Standard ECMA-262, 15.4.5.2

    All browsers support this behavior.


    Do the removed values get garbage collected properly?

    Yes. (See quotes above, and 15.4.5.1.)


    Is it an antipattern to set array length in Javascript?

    No, not really. While arrays are "exotic objects" in ES6-speak, the real crazily unique thing about arrays are their indexing, not setting the length property. You could replicate the same behavior with a property setter.

    It's true that property setters with non-subtle effects are somewhat unusual in JS, as their side-effects can be unobvious. But since .length has been there in Javascript from Day 0, it should be fairly widely understood.

    If you want an alternative, use .splice():

    // a is the array and n is the eventual length
    
    a.length = n;
    
    a.splice(n, a.length - n); // equivalent
    a.splice(n, a.length);     // also equivalent
    

    If I were avoid setting .length for some reason, it would be because it mutates the array, and I prefer immutable programming where reasonable. The immutable alternative is .slice().

    a.slice(0, n);  // returns a new array with the first n elements
    
    0 讨论(0)
  • 2020-12-08 13:50

    It's better to use slice because your intentions are clear.

    var truncated = a.slice(0,2)
    

    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

    0 讨论(0)
  • 2020-12-08 13:55

    Is it an antipattern to set array length in JavaScript?

    No. It would be OK to set it to truncate the array.

    Does it have decent browser support?

    Yes, see the compatiblity matrix here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length

    Do the removed values get garbage collected properly?

    Yes, they should. Will they actually get gced - you will need to profile the JavaScript code if this is a real concern.

    0 讨论(0)
提交回复
热议问题