Empty array with length different from zero. Can you explain me this? - javascript

var myNumb = 5;
var myArr = Array(myNumb);
console.log(myArr.length); // 5
console.log(myArr[0]) // undefined, as well as for myArr[1] myArr[2] myArr[3] myArr[4]
These lines create an array myArray that has a length of 5, but it's also said "an empty array", in fact myArr[0] is undefined, for example.
I can't understand how is possible to have an empty array with a length different from zero. If the array has not items, how can it have a length different from zero?

Positions in an array are still there even if they have no value, they are empty. Say you have the following code:
var myArray = new Array(5);
myArray[4] = 'Hello';
Do you expect 'Hello' to be in position 0 or 4? The answer is, of course, 4. The array has a length of 5, and even if indices 0 to 3 are empty, index 4 has a value.
As per MDN documentation, using the Array constructor yields the following:
If the only argument passed to the Array constructor is an integer
between 0 and (2^32)-1 (inclusive), this returns a new JavaScript array
with its length property set to that number (Note: this implies an
array of arrayLength empty slots, not slots with actual undefined
values). If the argument is any other number, a RangeError exception
is thrown.
JavaScript Array

Related

How to initialize array length and values simultaneously in new Array()?

Let’s consider, I have to initialize an Array with some values
So I can achieve this by writing following code.
var arr = new Array("a", "b", "c", "d")
console.log(arr)
Similarly, I have to determine the length of the array before using it.
So I can achieve this by following code.
var arr = new Array(5)
console.log(arr.length)
Finally, I have a following questions ?
Is it possible to initialize an array with array length and different values (not similar values) simultaneously using new Array() ?
How to initialize a single integer value using new Array() ?
EDIT:
here, different values refers there are some specific string values.
I know it is straightforward when using array literals. but that's not exactly what I want.
The answer for both questions is no. Looking at the docs, there are two overloads for the Array function.
A JavaScript array is initialized with the given elements, except in the case where a single argument is passed to the Array constructor and that argument is a number (see the arrayLength parameter below).
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 its length property set to that number.
Only these two possibilities exist, there is no overload for specifying both the size and the values of an array.
You can create and fill an array like so:
let a = Array(100).fill(null)
console.log(a)
Or to increment your filled values:
let i=0,a = Array(100).fill(0).flatMap(x=>[x+i++])
console.log(a)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
You could use .fill().
console.log(new Array(5).fill(2));
// [2, 2, 2, 2, 2]
Is it possible to initialize an array with array length and values simultaneously using new Array() ?
As far as I know, this isn't possible yet.
How to initialize a single integer value using new Array() ?
That would be k => new Array(1).fill(k). But if I had to choose, I'd use k => [k]. Note it is recommended not to use new Array() in other scenarios than to initialize it's lenght. But even then, you should rather be sure you are giving it an integer because the behaviour of new Array(n) is a bit erratic, and won't throw you an error when you wish it did.
Actually, I wish it was not possible to initialize an array with value using new Array(). The worst being using new Array(...args), whose behaviour will change dramatically when args is [5]. You should stick to [] arrays if you want to initialize an array with values.
Array("") gives [""]
Similarly Array([]) gives [[]] and Array({}), [{}]
Array(5) gives an array with 5 empty slots
Array(2.5) produces an Uncaught RangeError: Invalid array length.
Also, Array() gives []
Note: This is Chromium's behaviour. I didn't check Firefox.
There are few ways to create an array:
1) Literals
const a = [1,2,3];
console.log(a);
But you say you don't want to use it.
2) Array constructor:
const a = new Array(10); //array of length 10
console.log(a);
const b = new Array(1,2,3);
console.log(b); // array with elements 1,2,3
But you say that you don't want to go for it
3) Array.from
const a = Array.from(new Array(10), (val, ind) => ind); // array of 10 values and map applied to these elements
console.log(a);
Over these 3 ways, you have the Array.fill method, which can be called with static values only:
const a = new Array(10);
console.log(a.fill(5)); // array of 10 number elements with value of 5
Considering your case, maybe your solution could be to go with Array.from, using the map function you can provide as second parameter.
You could think to create some function like the following:
function createMyArray(length, start, end) {
return Array.from(new Array(length), (val, ind) => ind >= start && ind <= end ? ind : undefined);
}
console.log(createMyArray(5, 2, 4));
console.log(createMyArray(5, 1, 3));
console.log(createMyArray(10, 2, 6));
The question you should ask to yourself is: Where and how is the data I want to use coming from? Otherwise this is really too much vague
Is it possible to initialize an array with array length and different values (not similar values) simultaneously using new Array() ?
No you cannot do that with the Array constructor only.
An alternative way is to do it like this:
var a = ['a', 'b', 'c', 'd'];
a.length = 10;
console.log(a);
How to initialize a single integer value using new Array() ?
You can't. This is what happens when you try to do so according to the specification:
Array(len)
[...]
Let intLen be ToUint32(len).
If intLen ≠ len, throw a RangeError exception.
Let setStatus be Set(array, "length", intLen, true).
Assert: setStatus is not an abrupt completion.
Return array.
Use the other ways to create an array instead (e.g. [1] or Array.of(1)).
Here's a different but related take on initializing an array without using an array literal.
let arr = [...Array(10)].map((emptyItem, index) => index);
// [0,1,2,3,4,5,6,7,8,9]
I can't find documentation that matches how this expression is constructed, so I can't fully explain it. But it is using the spread syntax to spread 10 empty items into an array.

Javascript Array Showing Inconsistent Behavior

I am confused regarding javascript arrays and how the indices work in these arrays. The length of the array is always 0 no matter how many key value elements are there in the array. Also we can see that the array has only two elements provided that the key is string. Lets consider scenario 1, i have following code.
arr = [];
arr['home'] = 1234;
arr['cat'] = 12345;
console.log(arr.length);
console.log(arr);
Now consider second scenario, i have an empty array and i assign some number to the 20th index of the array. Then when i output the array, the length shows 21 with all the other locations being 'undefined'.
arr = [];
arr[20] = 20;
console.log(arr.length); // Length shows 20 Size of array increased to 21
Now in the third scenario i will assign both numbered indices and string indices and it shows another strange behavior. The length of the array doesn't count the value with string based index. Even though i have 4 number indices and one string based index. So the length should be 6 but the length shows 5.
arr = [];
arr[4] = 4;
arr['home'] = 'home';
console.log(arr);
Now i have two questions.Firstly, Why is the length function not considering string indexed item? Secondly, Why in the case of numbered indices, does the array size is increased to atleast that number?
You have to understand that JavaScript arrays are objects, with some additional behavior. Just like objects, you can assign properties to them.
If the property's name is a numeric string and there is no higher numeric key, the length property is updated. Non-numeric keys don't affect the length property.
The methods in Array.prototype (filter, slice, ...) only work with the numeric keys of the array.
Javascript doesn't have associative arrays like you see in PHP. It has arrays, which have a numerical index associated with the value, and then it has objects which are mapped key => value.
Javascript Arrays and Javascript Objects
const arr = [1, 2, 3, 4, 5, 6, 7];
console.log(arr.length); // outputs 7
const obj = {}
console.log(obj.length); // undefined
// set the key => value for obj from arr
arr.forEach(a => obj[a] = a);
console.log(obj[0]); // undefined
console.log(obj[1]); // 1
console.log(arr[0]); // 1
console.log(arr[1]); // 2
JS Bin
In the example above, you can see that arr is an array and its values are mapped index => value, while obj is an object and its values are mapped key => value. Objects can function as hash maps/associative arrays, but arrays cannot.
If you were to want to get the number of values in an object/hash map, you can always do...
Object.keys(obj).length
This is because Object.keys(...) returns the keys of an object as an array.
For an accurate answer, I should clarify that arrays are objects, however, they function differently than an object inherently does. Per the docs, arrays are "high-level, list-like objects"

How length property of an array works in javascript?

In javascript is it possible to directly set length property of an array. For example I can shorten the array like this:
var arr = [1, 2, 3, 4];
arr.length = 2;
console.log(arr); // Array [ 1, 2 ]
// arr[2], arr[3] are deleted
I would expect the length to be read-only (e.g. as in java).
As I understand, array in javascript is also an object:
console.log(typeof [1, 2, 3]); // object
How the length property works under the hood?
Array.prototype.length is a writable property of array.
Adding description from Array#lengthMDN
You can set the length property to truncate an array at any time. When you extend an array by changing its length property, the number of actual elements does not increase; for example, if you set length to 3 when it is currently 2, the array still contains only 2 elements. Thus, the length property does not necessarily indicate the number of defined values in the array.
This can be used to shorten an array.
As I understand, array in javascript is also an object:
console.log(typeof [1, 2, 3]); // object
Check Why does typeof array with objects return "Object" and not "Array"?
Generally, the length property is determined based on the highest index in the array.
Reading the length
1) For a dense array, this means that the length corresponds strictly to the number of elements:
var fruits = ['orange', 'apple', 'banana']; //fruits is a dense array
fruits.length // prints 3, the real count of elements
fruits.push('mango');
fruits.length // prints 4, one element was added
var empty = [];
empty.length // prints 0, empty array
The dense array does not have empties and the number of items corresponds to highestIndex + 1. In [3, 5, 7, 8] the highest index is 3 of element 8, thus the array size is 3 + 1 = 4.
2) In a sparse array (which has empties), the number of elements does not correspond to length value, but still is determined by the highest index:
var animals = ['cat', 'dog', , 'monkey']; // animals is sparse
animals.length // prints 4, but real number of elements is 3
var words = ['hello'];
words[6] = 'welcome'; //the highest index is 6. words is sparse
words.length //prints 7, based on highest index
Modifying the length
1) Modifying the property leads to cut the elements (if the new value is smaller than the highest index):
var numbers = [1, 3, 5, 7, 8];
numbers.length = 3; // modify the array length
numbers // prints [1, 3, 5], elements 7 and 8 are removed
2) or creating a sparse array (if the new value is bigger than the highest index):
var osTypes = ['OS X', 'Linux', 'Windows'];
osTypes.length = 5; // creating a sparse array. Elements at indexes 3 and 4
// do not exist
osTypes // prints ['OS X', 'Linux', 'Windows', , , ]
Please read this post, which covers in details everything about the length of an array.
The necessary steps to be fulfilled when length is being set on an Array is described on section 9.4.2.4 ArraySetLength of ES 6.0 language specification.
It deletes index properties from the old length of the array to the new length of the array according to step 19:
While newLen < oldLen repeat,
Set oldLen to oldLen – 1.
Let deleteSucceeded be A.[[Delete]](ToString(oldLen)).
Assert: deleteSucceeded is not an abrupt completion.
If deleteSucceeded is false, then
Set newLenDesc.[[Value]] to oldLen + 1.
If newWritable is false, set newLenDesc.[[Writable]] to false.
Let succeeded be OrdinaryDefineOwnProperty(A, "length", newLenDesc).
Assert: succeeded is not an abrupt completion.
Return false.
Whenever you set up a property for the array, it checks first to see if the property is length and if it is, it's supposed to do the ArraySetLength operation. This operation is described in section 9.4.2.1 [[DefineOwnProperty]] (this for Array Exotic Objects).
When the [[DefineOwnProperty]] internal method of an Array exotic object A is called with property key P, and Property Descriptor Desc the following steps are taken:
Assert: IsPropertyKey(P) is true.
If P is "length", then
Return ArraySetLength(A, Desc).
If it's not length and it's an indexed property the other steps in the operation are performed. Basically sets the value of the length property to the value of the index property + 1. As far as I can tell, the ArraySetLength operation isn't being used here to set the new length of the array.
Is it possible ?
Yes, it's possibly to directly set length property of an array.
You could set length of array to be shorten or higher ( to create sparsed array) then existing array. That's the way you can achieve desired behaviour.
Information about that from First edition of EcmaScript Standart-262, 15.4 :
Specifically, whenever a property is added whose name is an array
index, the length property is changed, if necessary, to be one more
than the numeric value of that array index; and whenever the length
property is changed, every property whose name is an array index whose
value is not smaller than the new length is automatically deleted.
So when you assigned lower value of length than it was before for an array deleting items( they would be collected by garbage collector ECMA-262, 15.4.5.1) from that array.
How length determined ?
The length of an array is the highest index + 1. However you can update length of Array in both direction ( decrease to delete elements and increase to create sparsed Array).
How to create Array with defined length ?
To create Array with defined length, pass length value into Array constructor as in code below:
var length = 10;
var newArray = Array(length);
console.log(newArray.length);// 10
Use full links:
Mozzilla MDN Array
Delete JavaScript Array Elements
W3Schools JavaScript Array length Property
arr = arr.slice(0, 2); will give you the first 2 elements of the array as a new array.
I would say this method is much more clear than using array.length = number to set the length of an array.
From the specs :
Array objects give special treatment to a certain class of property
names.
...
whenever a property of an Array object is created or changed, other
properties are adjusted as necessary to maintain this invariant.
Basically since the built-in array methods like join, slice, indexOf, etc all get affected by the property change, it is also necessary to update the Array.
In this case, since length is changed, there will be a change to the keys in the array.
You may take a look to Paragraph 9.4.2: Array Exotic Objects, and subsequent paragraph "ArraySetLength" where is described the algorithm:
An Array object is an exotic object that gives special treatment to array index property keys (see 6.1.7). A
property whose property name is an array index is also called an element. Every Array object has a length
property whose value is always a nonnegative integer less than 2 32 . The value of the length property is
numerically greater than the name of every own property whose name is an array index; whenever an own
property of an Array object is created or changed, other properties are adjusted as necessary to maintain this
invariant. Specifically, whenever an own property is added whose name is an array index, the value of the
length property is changed, if necessary, to be one more than the numeric value of that array index; and
whenever the value of the length property is changed, every own property whose name is an array index
whose value is not smaller than the new length is deleted. This constraint applies only to own properties of an
Array object and is unaffected by length or array index properties that may be inherited from its prototypes.

What is the length property of the array x?

What would the length property of the array x be?
var x=new Array();
x[0]="Monday";
x[1]="Tuesday";
x[3]="Thursday";
It would be 4.
The .length property is defined to be one more than the numeric value of the largest integer-like property name. The largest (when interpreted as a number) such property name in the example code is 3, so the .length value is therefor 4.
If you set a property of an array, such that the property name is an integer (or a string that looks like an integer), then length is updated to be one more than that integer value. Symmetrically, if you set length to some value, then all properties whose names are integers greater than or equal to the new value are implicitly deleted.
if you want to know the length of your array 'x' then you can just do something like:
var length = x.length;
keep in mind that arrays are 0 based. So the length here will be 4, however, if you want to access the indexes of your array you will need to use 0, 1, 2, 3.
further, if you want to know the length, after getting your var length you could do either of the following:
console.log(length);
alert(length);

JavaScript array's length method

Can anyone explain why the second alert says 0 ?
var pollData = new Array();
pollData['pollType'] = 2;
alert(pollData['pollType']); // This prints 2
alert(pollData.length); // This prints 0 ??
The length of the array is only changed when you add numeric indexes. For example,
pollData["randomString"] = 23;
has no effect on length, but
var pollData = [];
pollData["45"] = "Hello";
pollData.length; // 46
changes the length to 46. Note that it doesn't matter if the key was a number or a string, as long as it is a numeric integer.
Besides, you are not supposed to use arrays in this manner. Consider it more of a side effect, since arrays are objects too, and in JavaScript any object can hold arbitrary keys as strings.
Because you haven't put anything into the array yet. You've only been assigning to a dynamically-created pollType attribute on the array object.
If you use numeric indices, then the array automagically takes care of length. For example:
var arr = [ ]; // same as new Array()
arr[2] = 'Banana!';
alert(arr.length); // prints 3 (indexes 0 through 2 were created)
The length property takes into consideration only those members of the array which names are indexes (like '1', '2', '3', ... ).
Arrays in JavaScript have numeric indexes only.
Use an object, which is essentially what you are doing above, setting properties on that array object.
array.length returns how many values are stored in the array. The first alert is returning the value of the position 'pollType'.
The reference guide I always use when needing help with javascript arrays is this page http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
I'd also read what it says under the heading Javascript Does Not Support Associative Arrays, as you may run into problems with this also.
var pollData = Array();
function test() {
pollData[0] = 2
alert(pollData[0]);
alert(pollData.length);
}
//[x] is the array position; hence ['polltype'] is causing issues

Categories

Resources