Array.map doesn't seem to work on uninitialized arrays

后端 未结 8 1916
忘了有多久
忘了有多久 2020-12-03 10:35

I\'m trying to set default values on an uninitialized array using the map function but it doesn\'t seem to work, any ideas on how to set default values?

Consider thi

相关标签:
8条回答
  • 2020-12-03 10:57

    With .map(), undefined elements are skipped and not passed to the callback so if you have an array with no elements that actually contain anything, then the callback is never called.

    From the ECMA script 262, 5.1 specification, section 15.4.4.19:

    callbackfn is called only for elements of the array which actually exist; it is not called for missing elements of the array.

    0 讨论(0)
  • 2020-12-03 10:58

    Also possible solution without Array.prototype.fill:

    [...Array(10)].map((_, idx) => idx); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    0 讨论(0)
  • 2020-12-03 11:01

    That's how it's described by the ECMAScript Language specification

    Here's the relevant part of Array.prototype.map, as described by (§15.4.4.19)

    • ...
    • 8. Repeat, while k < len
      • a) Let Pk be ToString(k).
      • b) Let kPresent be the result of calling the [[HasProperty]] internal method of O with argument Pk.
      • c) If kPresent is true, then
        • do the magic
    • ...

    Since there is no initilized member in your array, calling e.g new Array (1337).hasOwnProperty (42)evaluates to false, hence the condition in step 8.c is not met.

    You can however use a little "hack" to do what you want.

    Array.apply(null, { length: 5 }).map(Number.call, Number) //[0, 1, 2, 3, 4]

    How this works has been thouroughly explained by @Zirak

    0 讨论(0)
  • 2020-12-03 11:02

    If you'd like to fill an array, you can use Array(5).fill() and the methods will then work as expected--see the alternate related answer from aasha7. Older pre-fill approaches include:

    Array.apply(null, new Array(5)).map(function() { return 0; });
    // [ 0, 0, 0, 0, 0 ]
    

    After some reading one of the posts linked in the comments, I found this can also be written as

    Array.apply(null, {length: 5}).map(function() { return 0; });
    

    However, trying to use .map on undefined values will not work.

    x = new Array(10);
    x.map(function() { console.log("hello"); });
    
    // so sad, no "hello"
    // [ , , , , , , , , ,  ]
    

    .map will skip over undefined values :(

    0 讨论(0)
  • 2020-12-03 11:02

    I'd just like to point out that you can now do:

    Array(2).fill().map(_ => 4);
    

    This will return [4, 4].

    0 讨论(0)
  • 2020-12-03 11:03

    The .map() function skips entries that have never been assigned values. Thus on a newly-constructed array like yours, it does essentially nothing.

    Here is the MDN description.

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