Found the problem

While studying VUE today, I found a snippet of code in one of the examples in the documentation

  Array.apply(null, { length: 20 }).map(function () {
    return createElement('p'.'hi')})// The purpose is to create a loop of 20 times
Copy the code

This reminds me of when I was learning to write a demo and wanted to use forEach to do a loop several times. I wrote it like this

  Array(10).forEach(function(){
    // do something
  })
Copy the code

The result is that the loop does not enter. The reasons for querying MDN are as follows:

The forEach method performs a callback forEach item in the array that has a valid value, in ascending order, and those items that have been deleted (using the delete method, etc.) or have not been initialized are >> skipped (but not those with undefined value) (for example, on a sparse array).

Highlight: items that are not initialized will be skipped

The Array created by Array(10) or New Array(10) is an empty Array with a length attribute. Each element in the Array has not been assigned (initialized), so forEach map and other methods are skipped

  Array(10) // [empty × 10] length: 10
  new Array(10) // [empty × 10] length: 10
Copy the code

To solve the problem

But with the method you saw today you can create an array that can be traversed by methods like forEach. Why?

  // These three methods return an array of length 10, and each element is assigned undefined
  Array.apply(null, {length: 10}) 
  Array.apply(null.Array(10)) 
  Array.apply(null.new Array(10)) 

  // [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
Copy the code

Here’s a review of the Array constructor. Here’s a reference to MDN

The Array constructor creates a JavaScript Array based on the given element, except when there is only one argument and it is a number: An integer between 0 and 232-1 returns an array object whose length is equal to arrayLength. It cannot be taken for granted that it contains an arrayLength element with a value of undefined. Note that this latter case applies only to arrays created with Array constructors, not Array literals created with square brackets.

But when there is only one parameter and it is a number, the group does not contain any actual elements, so it cannot be taken for granted that it contains elements of arrayLength whose value is undefined, that is, the elements in the created array are not assigned (initialized)

Then review the use of the array. apply method

The array.apply () method takes two arguments, the first of which is the context specified when it is called; The second is an array or an array-like object;

  Array.apply(null, {length: 10})
  Array.apply(null.Array(10))
  Array.apply(null.new Array(10))

  // These three methods are equivalent to

  Array(undefined.undefined.undefined,...).Copy the code

Since the Array constructor creates an Array based on the given arguments (if not just one argument and a number), passing an empty Array with length 10 through array. apply is equivalent to passing the value of each element in an empty Array one by one to the Array() method. Each element in an empty array, such as emptyArr[0], is undefined

I’ll write a pseudocode here just to make it easier to understand; Pseudo code:

  var arrayLike = {length: 2} left leftArray.apply(null, arrayLike) left leftArray(arrayLike[0], arrayLike[1]) // Pass the value of each element in an empty Array to the Array() methodLeft leftArray(undefined.undefined) // The value of each element in an empty array is undefined

  [undefined, undefined]
Copy the code

Is that why array.apply () makes it possible to generate an Array that can be traversed by methods like forEach

  Array.apply(null, {length: 5}) 
  // This is actually the same thing as this
  Array(undefined.undefined.undefined.undefined.undefined)

  // [undefined, undefined, undefined, undefined, undefined]
  // The elements in the generated array are initialized to undefined, which can be traversed by methods such as forEach
Copy the code

In addition, ES6 provides a new API, array.from (), that can do the same

Below is a quote from Ruan Yifeng’s Introduction to ECMAScript 6

The array. from method also supports array-like objects. The so-called array-like object has only one essential feature, that is, it must have the length attribute. Therefore, any > object with a length attribute can be converted to an Array using the array. from method

  Array.from({length: 5})
  // [undefined, undefined, undefined, undefined, undefined]
Copy the code

Another way of writing ES6

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