Array constructor not working as expected [duplicate] - javascript

This question already has answers here:
Undefined values in Array(len) initializer
(5 answers)
Closed 6 years ago.
I want to create empty array with fixed length, and then use .map on it to return new array. However, it's not working as expected.
According to mdn docs:
If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with length set to that number.
new Array(3) returns [undefined × 3]. Shouldn't it be: [undefined, undefined, undefined]?
Let's consider following examples:
1) Not working.
var a = new Array(3);
a.map((x, i) => i); // [undefined × 3]
2) Working.
var a = Array.apply(null, new Array(3));
a.map((x, i) => i); // [0, 1, 2]
I tested this on latest Google Chrome Canary.

From the MDN: this returns a new JavaScript array with length set to that number
The Array created by new Array(n) does not have any elements, only a length. That's why you can't map the (not existing) elements.

map skips over undefined elements, by design.
From the documentation:
callback is invoked only for indexes of the array which have assigned values
There are many questions here on SO related to this topic, and providing ways to create arrays that map will operate on all elements of, such as
new Array(3) . fill() . map(...
to take just one example, using the new Array#fill method.

An example in a addition to CodeiSirs answer:
// foo and bar are identical. They are arrays with length 3 and no indices.
var foo = new Array(3);
var bar = [];
bar.length = 3;
console.log(foo);
console.log(bar);
// This is different. It has 3 indices with the value undefined.
var pez = [undefined, undefined, undefined];
console.log(pez);
The console displays new Array(3) kind of weird because it's not the same as [undefined, undefined, undefined]

Related

new Array(n) creates empty arrays; [...new Array(n)] creates undefined arrays. Why? [duplicate]

This question already has answers here:
JavaScript "new Array(n)" and "Array.prototype.map" weirdness
(14 answers)
Closed 3 years ago.
new Array(n) generates an array of empty numbers. e.g. new Array(5) generates [empty × 5]
[...new Array(n)] generates an array of undefined numbers. e.g. [...new Array(5)] generates [undefined, undefined, undefined, undefined, undefined]
Which part of the process converts empty values in undefined values?
Spread Operator creates a new array of same length, copying all elements from source array.
for (let i = 0; i < source.length; i++)
destination[i] = source[i] // Which is evaluated to `undefined`
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
One interesting thing to do here is to check what transpilers will do:
Babel
TypeScript
Both Babel and TypeScript transpile to the same loop iterating over source array, so passing through each undefined value.

Array.of() vs new Array() [duplicate]

This question already has answers here:
What is the use case for Javascript's (ES6) Array.of()?
(4 answers)
Closed 4 years ago.
console.log(Array.of('a','b','c'))
console.log(new Array('a','b','c'))
What is the difference between them and which one is best to use?
Array#of documentation
The difference between Array.of() and the Array constructor is in the
handling of integer arguments: Array.of(7) creates an array with a
single element, 7, whereas Array(7) creates an empty array with a
length property of 7 (Note: this implies an array of 7 empty slots,
not slots with actual undefined values).
The first result of google brings the answer right away
The difference between Array.of() and the Array constructor is in the
handling of integer arguments: Array.of(7) creates an array with a
single element, 7, whereas Array(7) creates an empty array with a
length property of 7 (Note: this implies an array of 7 empty slots,
not slots with actual undefined values).
The difference is when you pass an int as parameter
Array.of(2)
creates the array [2]
new Array(2)
creates the array [empty x 2]

Javascript mapping of new Array() [duplicate]

This question already has answers here:
Using Array.map with new Array constructor
(5 answers)
Closed 5 years ago.
new Array(3)returns an array of length 3 containing 3 undefineds which is equivalent to [undefined, undefined, undefined];
However,
[undefined, undefined, undefined].map((val, i) => i) produces the expected result of [0, 1, 2]. But new Array(3).map((val, i) => i) produces [undefined, undefined, undefined], as if the map function had not effect whatsoever.
Could anyone explain why?
EDIT
Looks like there is a flaw in my understanding of new Array(). It does NOT create a new array. It creates an object with key length equal to the argument passed in. Thanks for the answers and comments.
Btw if you do need an array like [undefined, undefined, undefined] to iterate/map over, or for anything then [...new Array(m)] should do the trick.
An important thing to understand that there is no array type in javascript. Built-in Array is just a convenience wrapped over the standard Object. The only difference is that Arrays have the length property, computed in a special way.
new Array(3) returns an object with a single length field. It doesn't contain any other keys.
{
length: 3
}
[undefined, undefined, undefined] creates an object with 3 numeric slots:
{
length: 3
0: undefined,
1: undefined,
2: undefined,
}
That makes difference, because map and other iterators look for numeric keys that actually exist in the object. The logic behind map, forEach and friends is like this:
for (var i = 0; i < A.length; i++)
if (A.hasOwnProperty(i))
do something with A[i]
new Array(3)returns an array of length 3 containing 3 undefineds which is equivalent to [undefined, undefined, undefined];
Not according to MDN:
this implies an array of arrayLength empty slots, not slots with actual undefined values
when you do new Array(3) Javascript reserves memory for an Array of 3 elements, but does not define any of them.
When you do create an array via [undefined, undefined undefined] it actually creates 3 elements which value is undefined each of them (therefore, it is an array of length 3).

Creating array of arrays different behavior [duplicate]

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 6 years ago.
I have found that these two different methods of creating an array of arrays produce different behaviors:
// Method 1
for (var arr1 = []; arr.push([]) < len;) {}
// Method 2
var arr2 = new Array(len).fill([])
The arrays created look the same in the console, however they behave differently in my code. What could be causing this?
The difference is that in the 1st method each index points to a different array, while in the Array#fill all indexes point to the same array.
Note: the 1st method will not create an array of arrays
var len = 3;
var arr1 = [];
// Method 1
for (var arr1 = []; arr1.push([]) < len;) {} // new sub array is pushed into arr1
// Method 2
var arr2 = new Array(len).fill([]) // each place in the array is filled with a reference to the same array
arr1[0].push(1); // push to the 1st element of arr1
arr2[0].push(1); // push to the 1st element of arr2
console.log('arr1: ', JSON.stringify(arr1)); // only the 1st sub array contains 1
console.log('arr2: ', JSON.stringify(arr2)); // all sub arrays contain 1
Update: While the answer below is technically accurate, and is another difference between the two methods, #Ori Drori's answer is almost certainly what the OP is looking for.
I'll take a stab at this, but more context would be helpful.
In common practice, these two statements typically behave the same, but there is a key difference - when you use the new keyword, the Javascript interpreter calls the Array constructor.
If you were to overwrite the Array constructor, this would only apply to arr2 which was defined with the new keyword. arr1 created with the array literal would still be a Javascript array.
As an example, let's say I wrote the following code:
function Array() {
}
Method 1 would still work, but Method 2 would return a TypeError indicating that fill is not a function.
Interestingly, using the Array literal (Method 1) still calls the Array constructor, so if I did a console.log("test"); within the Array construction this would still be printed to the console when using either method. BUT, when the Array literal (Method 1) is used, the object itself still remains a standard Javascript array even if the Array constructor is overwritten.

Why pushing undefined to an empty array give 1? [duplicate]

This question already has answers here:
Why does Array.prototype.push return the new length instead of something more useful?
(6 answers)
Closed 4 months ago.
If I do
var a = [].push(undefined);
console.log(a);
it gives output as 1 even though undefined was pushed to the array. Any idea why?
You're testing it the wrong way. a is not defined as the array, as I think you suppose it to be. Try this:
var a = []
a.push(undefined);
console.log(a);
You are assigning the return value of push function to variable a. push returns the length of the array after pushing the current element in context. So, it returns 1 after pushing undefined in the array.
its pushing the length of array inside not the elements
example
var a = [].push(5,6,7,8);
console.log(a); //gives 4
Push returns the new length of the array, and thats what is stored in a
There was no explicit check has been done when assigning a new property to array object. Assigning a new property in the sense, setting 0,1,2..n properties with values, based on the length of the array.
Repeat, while items is not empty
Remove the first element from items and let E be the value of the element.
Let setStatus be Set(O, ToString(len), E, true).
ReturnIfAbrupt(setStatus).
Let len be len+1.
You can see it here. Step 8.

Categories

Resources