11

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?

madox2
  • 49,493
  • 17
  • 99
  • 99
  • You have [.slice](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) in JS – Alon Eitan Jan 24 '16 at 14:15
  • do you want to print only the first two items from list? – pivanchy Jan 24 '16 at 14:15
  • 2
    By definition in js it is possible to set the length of the array by setting the length attribute. See: http://www.w3schools.com/jsref/jsref_length_array.asp – TheBrain Jan 24 '16 at 14:17
  • 1
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length – Daniel Krom Jan 24 '16 at 14:19
  • 1
    [Shortening an array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length#Shortening_an_array) – Tushar Jan 24 '16 at 14:21

7 Answers7

5

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"?

Community
  • 1
  • 1
Tushar
  • 85,780
  • 21
  • 159
  • 179
2

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.

Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41
1

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:

Community
  • 1
  • 1
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82
1

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.

MinusFour
  • 13,913
  • 3
  • 30
  • 39
0

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.

J0B
  • 1,648
  • 1
  • 12
  • 24
0

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.

loxxy
  • 12,990
  • 2
  • 25
  • 56
0

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.

gaetanoM
  • 41,594
  • 6
  • 42
  • 61