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

前端 未结 7 858
广开言路
广开言路 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条回答
  •  旧时难觅i
    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
    

提交回复
热议问题