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
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.
I am using the following pattern to index an injection from pairs of numbers to numbers:
var myHash = {};
...
for (... billion of iterations ...)
var x = someNum;
var y = otherNum;
myHash[x + "," + y] = z;
The problem with this code is that I'm using a string as the key of myHash, which has been tested to be much slower than integer keys. My question is: what is a more intelligent way to combine 2 numbers before using them as keys of an object? I.E., how to combine 2 doubles into an unique Integer?
There is the definition of an array in JavaScript:
Array objects give special treatment to a certain class of property names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232 - 1. 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 232. The value of the length property is numerically greater than the name of every property whose name is an array index; whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. 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. 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.
In other words, if the index you specify is a number representing an integer between 0 and 0xFFFFFFFE, then it is used as an array index. Any other value is taken as a string and it is used to create an object member instead of an array item.
So if you have constraints on your indices which would fit the valid range (0 to 0xFFFFFFFE) then you're good. Otherwise, what you have is probably the fastest.
So the following represents string indices which are members of object myHash:
myHash[x + "," + y] = z;
Someone mentioned using an array of arrays. That would not help you. You'd get many arrays instead of many strings. It would probably be about the same if not slower. The idea is something like this:
myHash[x] = []; // initialize the sub-array (must be done only once per value of 'x'
myHash[x][y] = z; // save z in that array
I do not recommend the double array because it will initialize one array for each value of 'x' on top of myHash and that probably not any faster than having the string concatenation (especially because you'll have to test whether the myHash[x] array was already defined or not...).
So... it is possible to write:
myHash[3.3] = "that worked?";
But if after that you check out the length, you'll notice it is zero:
console.log("Hash length = " + myHash.length);
This is because 3.3 is not an integer.
var myArray = new Array();
myArray['112'] = 0;
myArray.length
Why is length 113 in above sample? Shouldn't '112' add a object property for the array and create something similar to myArray = {"112":0}?
Besides this, why is the length 113 and not 1? Since myArray actually only contains 1 value
The array length is one more than the highest index, so you get 113.
No. The '112' string and a pure numeric 112 evaluate to the same thing when JS is doing the array lookup, so you get a slot in the array rather than a property.
Simplest to think of a JS Array indexes as properties that happen to be numbers, even in string form. It's more chameleonic than you'd think at first.
But if you add a property with some nonnumeric name, like myArray['foo'], it will do as you expect and the length won't change.
Consider this simple example:
var aa = [];
aa[3] = 'three';
alert( aa.length // 4
+ '\n' + aa[2] // undefined
+ '\n' + aa.hasOwnProperty('2') // false
);
The number 3 is used to assign the property name, but it is converted to a string and used as a standard property name (i.e. the string "3").
Adding a property named "3" has created one property and set the length to 4 since the length is always set to one more than the largest non-negative integer property name.
No other property is created, the array is "sparse", i.e. it doesn't have sequentially named (numbered) members. A for..in loop can also be used to see that there is only one property.
You got array of 0..112 elements - in total length of 113 elements.
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