preface

An array of specified length that can be traversed:

  • Traversable: It can passmap,forEachAnd so on to iterate over a number of elements.
  • Specified length: An array has a specified number of array elements.

basis

Creating an array of specified length is very simple. The length of the array instance is initialized directly when the array is created.

new Array(5) /* is equivalent to */ Array().length = 5;

/ * * (5) [empty x5] length: 5 __proto__ : Array (0) * * /
Copy the code

The array constructor creates an instance of the array and initializes its length, just changing the value of the array instance’s Length property. The actual array elements that the array has are still [empty × 5].

const i = 0;
Array(5).forEach((item,index) = >{console.log(i)}); // It can be found that I does not output.
Copy the code

There is no need to initialize the length of an array, given the dynamic nature of the array size in JavaScript, because many programs use the array length attribute to determine the size of the array, which can lead to unexpected problems.


The simplest and most crude way to create an array is to manually pass in all the array elements.

Array(0.1.2.3.4);
/**
(10) [1, 2, 3, 4, 5
0: 0
1: 1
2: 2
3: 3
4: 4
length: 5
**/
Copy the code

But this approach is too extreme, so we need to find a more general approach:

ES5, Apply method and class array

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

The first time I saw this was in the official Vue documentation.

This approach has two elements:

  1. applyThe array extension as a parameter is broken down and passed as a normal parameter.
  2. {length:5}It’s not an ordinary object, it’s a Like Array.

What is a class array?

  • Accessible by index, and ownedlengthProperty object
  • There is nopush,popMethods like real arrays.
Like Array Type
{length:10} Object
NodeList [body.docs] {0: body.docs, length: 1} NodeList
HTMLCollection [div.sidebar] {0: div.sidebar, length: 1} HTMLCollection

Now let’s execute the following code and observe the output:

function applyTest() {
  console.log(arguments);
}

applyTest.apply(null, { length: 5 });
applyTest.apply(null[0.1.2.3.4]);

/** > Object { 0: undefined, 1: undefined, 2: undefined, 3: undefined, 4: undefined } > Object { 0: 0, 1: 1, 2: 2, 3: 3, 4, 4} * * /
Copy the code

This is a beautiful coincidence when the Like Array meets the Apply method. It is this coincidence that allows us to pass in multiple arguments at a time to the array constructor in an automatic manner instead of manually.

A digression, because class Array has a length attribute and can traverse through the index of the characteristics, so we can use the Array. The prototype. Slice. Call ({1-0, length: 1}). Convert it to a real array.

Array.prototype.slice.call(document.querySelectorAll('div'));
Copy the code

ES6 extension operator

[...Array(5)]; //[undefined, undefined, undefined, undefined, undefined]
Copy the code

🤔? What if we use the extension operator to convert a Like Array?

{[...length:5}]; //VM146:1 Uncaught TypeError: {(intermediate value)} is not iterable
Copy the code

The ES6 extension operator makes some judgments on its internal implementation based on different cases:

  1. If the extended array is not an empty array, directly[].concat(arr)Merges the array to be extended.
  2. If the extended array is an empty array, based on that arraylengthThe length is traversed, and is filled if the array element corresponding to the array subscript is empty during the loopundefined.
  3. If the object to be extended is not an array, check whether the object has an Iterator interface, otherwise throw an error.

With a basic understanding of how the extension operator works, we can now create an iterator to put into the created class array:

{[...length: 5[Symbol.iterator]: Array.prototype[Symbol.iterator] }];
Copy the code

After execution, an array with five undefined elements is successfully created.

A more concise ES6 approach

Array(5).fill(0);
Copy the code

The last

There are many other ways to create traversable arrays of specified length, such as:

Array.from({ length: 5 }, () = > 0);
Array.apply(null.Array(5)).map(() = > 0);
Copy the code

However, I feel that the three ways introduced above are the most representative. In addition, Vue’s V-for =” I in 10″ command can also support rendering content as many times as specified.