How does the length property of an array work in javascript?

In javascript, you can directly set the length property of an array. For example, I can shorten the array as follows:

 var arr = [1, 2, 3, 4]; arr.length = 2; console.log(arr); // Array [ 1, 2 ] // arr[2], arr[3] are deleted 

I would expect length be read-only (e.g. like in java).

As I understand it, an array in javascript is also an object:

 console.log(typeof [1, 2, 3]); // object 

How does the length property work under the hood?

+5
source share
7 answers

Array.prototype.length is a property of a writable array.

Adding a Description from Array#length MDN

You can set the length property to truncate the array at any time. When you expand an array by changing its length property, the number of actual elements does not increase; for example, if you set the 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 shrink an array .


As I understand it, an array in javascript is also an object:

 console.log(typeof [1, 2, 3]); // object 

Check Why the typeof array with objects returns "Object" and not "Array",

+2
source

Typically, the length property is determined based on the highest index in the array.

Reading length

1) For a solid 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 

A dense array has no empty media, and the number of elements corresponds to highestIndex + 1 . In [3, 5, 7, 8] largest index is 3 element 8 , so the size of the array is 3 + 1 = 4 .

2) In the sparse array (which has empty), the number of elements does not match the length value, but is still 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 

Change length

1) Changing the property leads to cutting out the elements (if the new value is less 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 greater 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 details the entire length array.

+2
source

arr = arr.slice(0, 2); will give you the first 2 elements of the array as a new array.

I would say that this method is much more clear than using array.length = number to set the length of the array.

0
source

Is it possible?

Yes, it is possible to directly set the length property for an array.

You can set the length of the array, which should be reduced or higher (to create a sparse array), and then the existing array. This is a way to achieve the desired behavior.

Information on this from the first version of EcmaScript Standart-262, 15.4 :

In particular, whenever a property whose name is an index array is added, the length property is changed, if necessary, to be one more than the numeric value of this array index; and whenever the length of the property changes, each property whose name is the index of the array, a value no less than the new length is automatically deleted.

So, when you assigned a smaller length value than before, for the array to delete elements (they will be collected by the garbage collector ECMA-262, 15.4.5.1 ) from this array.

How is the length determined?

The length of the array is the highest index + 1 . However, you can update the length of the Array in both directions (decrease to remove elements and increase to create a sparse array).

How to create an array with a specific length?

To create an array with a given length, enter the length length in the Array constructor, as in the code below:

 var length = 10; var newArray = Array(length); console.log(newArray.length);// 10 

Use full links:

0
source

From the specifications :

Array objects give a special approach to a specific class of property names.

...

when an Array object property is created or modified, other properties are adjusted as necessary to maintain this invariant.

Basically, since the built-in array methods, such as join, slice, indexOf, etc., are all affected by property changes, it is also necessary to update the array.

In this case, since the length is changed, the keys in the array will change.

0
source

You can take a look at Clause 9.4.2: Extreme array objects and the subsequent paragraph "ArraySetLength", which describes the algorithm:

An Array object is an exotic object that provides a special reference to the properties of array index properties (see 6.1.7). a property whose property name is an array index is also called an element. Each Array object has a property length, the value of which is always a non-negative integer less than 2 32. The value of the length property is numerically greater than the name of each proper property, the name of which is the index of the array; when an Array object property is created or modified, other properties are adjusted as necessary to maintain this invariant. In particular, whenever a property of its own is added, whose name is the index of the array, if necessary, the value of the length changes, which should be greater than the numerical value of this index of the array; and also when the value of the length property changes, each property of its own, whose name is an array index whose value is no less than the new length. This restriction applies only to the intrinsic properties of an Array Object and does not depend on the properties of a length index or an array that can be inherited from its prototypes.

0
source

The necessary steps to be taken when setting length in an array are described in Section 9.4.2.4 ArraySetLength the ES 6.0 Language Specification.

It removes the index properties from the old array length to the new array length 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 configure a property for an array, it first checks to see if it has a length property, and if so, it should perform an ArraySetLength operation. This operation is described in section 9.4.2.1 [[DefineOwnProperty]] (this is for exotic Array objects).

When the internal method [[DefineOwnProperty]] of the Array object of the exotic object A with the property key P and the desc property descriptor is called, the following steps are performed:

 Assert: IsPropertyKey(P) is true. If P is "length", then Return ArraySetLength(A, Desc). 

If it is not length , and it is an indexed property, other steps in the operation are performed. Basically, the value of the length property is set to the value of the property index + 1. As far as I can tell, the ArraySetLength operation is not used here to set the new length of the array.

0
source

Source: https://habr.com/ru/post/1241355/


All Articles