Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
340 views
in Technique[技术] by (71.8m points)

javascript - Why does Array.apply(null, [args]) act inconsistently when dealing with sparse arrays?

I recently discovered the following snippet of code on SO to aid in quickly populating an array with default values:

Array.apply(null, new Array(3)).map(function() {return 0;});

Given the behavior of the Array constructor and the apply method, the above snippet can also be rewritten as such:

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

This technique is also useful when dealing with sparse arrays that you wish to populate with default values:

var sparseArr = [3,,,4,1,,],
    denseArr = Array.apply(null, sparseArr).map(function(e) {
      return e === undefined ? 0 : e;
    });

// denseArr = [3,0,0,4,1,0]

However it is therein that two oddities arise:

  1. If the final term of of sparseArr is undefined, that term is not mapped in denseArr
  2. If sparseArr contains only a single term (e.g. sparseArr = [1]) or a single term followed by a single trailing undefined term (e.g. sparseArr = [1,]), the resulting denseArr equals [undefined x 1]

Can anyone explain this behavior?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

new Array(3) […] can also be rewritten as [undefined, undefined, undefined]

No - as you just have seen, the array constructor creates sparse arrays so it should be rewritten as [,,,].

If the final term of of sparseArr is undefined

Nope. You're forgetting about trailing commata, which are optional since EcmaScript 5. Actually [1] is just equivalent to [1,] (both have a length of 1).

To get sparse "slots", you will have to add additional commata:

[] // empty array
[,] // empty array
[,,] // [undefined x 1]
[,,,] // [undefined x 2]

If sparseArr contains only a single term, the resulting denseArr equals [undefined x N]

Consider what it means to call the apply method:

Array.apply(null, [3,,4,1]) ≡ Array(3, undefined, 4, 1)
Array.apply(null, [3,4]) ≡ Array(3, 4)
Array.apply(null, [1]) ≡ Array(1)

And you know what the Array constructor does when being called with a single numeric arguments - it creates a sparse array of that length…


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...