I have been coming across the term "Array-Like Object" a lot in JavaScript. What is it? What's the difference between it and a normal array? What's the difference between an array-like object and a normal object ?
What is it?
An Object which has a length property of a non-negative Integer, and usually some indexed properties. For example
var ao1 = {length: 0}, // like []
ao2 = {0: 'foo', 5: 'bar', length: 6}; // like ["foo", undefined × 4, "bar"]
You can convert Array-like Objects to their Array counterparts using Array.prototype.slice
var arr = Array.prototype.slice.call(ao1); // []
Whats the difference between it and a normal array?
It's not constructed by Array
or with an Array literal []
, and so (usually) won't inherit from Array.prototype
. The length property will not usually automatically update either.
ao1 instanceof Array; // false
ao1[0] = 'foo';
ao1.length; // 0, did not update automatically
Whats the difference between an array-like object and a normal object?
There is no difference. Even normal Arrays are Objects in JavaScript
ao1 instanceof Object; // true
[] instanceof Object; // true
and so (usually) won't inherit from Array.prototype
Care to elaborate on the "usually" part ? Isn't something not an array-like but an array if it inherits from Array.prototype
? –
Wellappointed Array.isArray(Object.create(Array.prototype)); // false
. If you use ES6+ class A2 extends Array
and super
, you will get Arrays Array.isArray(new A2); // true
–
Emitter isArray
method since it uses the internal [[class]]
property behind the scenes, than it being proof that an object with Array.prototype
is an array-like, rather, an object that has array methods available to it (via inheriting from Array.prototype
, this also means it has a length
property) and is numerically indexed is not an array-like, it is an array. –
Wellappointed [[class]]
property ? or is there an entirely different mechanism at play here ? –
Wellappointed function Foo() {}; Foo.prototype = Object.create(Array.prototype); f = new Foo;
consider how f[0] = 1; f.length; // => 0
. This means it isn't a true Array as setting an index doesn't have the expected side-effects on length. Doing the same with ES6+ does have side effects on length –
Emitter length
property automatically updating/not-updaing. –
Wellappointed var objSort = {0: 1, 1: 7, 2: 2}
,why it doesnt get sorted by Array.prototype.sort.call(objSort); ?
–
Elspeth 0
.i.e var objSort = {1: 10, 2: 30,3: 20,length:3}
doesn't gets sorted like var objSort = {0: 10, 1: 30, 2: 20}
does ` –
Elspeth You can convert Array-like Objects to their Array counterparts
, the true thing is you can convert every object to an empty array by this way. So how can we create an Array-like object which we can be formatted to an array by Array.prototype.slice
just like on arguments
. –
Edmundson The famous HTMLCollection
(documentation) and the arguments
(documentation) are array-like object that automatically created.
Some quick array-like (e.g HTMLCollection
) differences between real array examples:
var realArray = ['value1', 'value2'];
var arrayLike = document.forms;
Similarities:
The length getter is the same:
arrayLike.length; // returns 2;
realArray.length; // returns 2; //there are 2 forms in the DOM.
The indexed getter is the same:
arrayLike[0]; // returns an element.
realArray[0]; // returns an element. ('value')
They are both objects
:
typeof arrayLike; // returns "object"
typeof realArray; // returns "object"
Differences:
In array-like the join()
, concat()
, includes()
etc, methods are not a functions:
arrayLike.join(", "); // returns Uncaught TypeError: arrayLike.join is not a function (also relevant to `concat()`, `includes()` etc.)
realArray.join(", "); // returns "value1, value2"
The array like is not really an array:
Array.isArray(arrayLike); //returns "false"
Array.isArray(realArray); //returns "true"
In array like you can't set the length property:
arrayLike.length = 1;
arrayLike.length; //return 2; //there are 2 forms in the DOM.
realArray.length = 1;
realArray.length; //return 1;
To begin with, an array is a specialised object. Specialised in that:
- There is a special literal syntax
[ … ]
- There is a
length
property which is automatically updated - The array prototype includes the functions that you normally expect from an array
The other obvious feature is that all elements have a numeric index.
From JavaScript’s point of view any object which has a length
property is close enough to be regarded as an array-like object:
var arrayLikeObject = {
length: 3,
name: 'thing',
'1': 'hello'
};
console.log(arrayLikeObject);
The length
property doesn’t have to be correct. Even in a normal array, it’s possible to force the length
to be other than the number of actual elements. The missing elements all return undefined
.
You can convert from an array-like object to a real array using Array.from()
. This function will take various values, but the simplest is something like:
var arrayLikeObject = {
length: 3,
name: 'thing',
'1': 'hello'
};
var array = Array.from(arrayLikeObject);
console.log(array);
From here on, the array has all the usual properties and methods. In the above example, the property [1]
is copied into the new array, but the element [name]
is not, since it doesn’t belong in a real array.
The Array.from()
function also accepts a mapping function as a second parameter. This allows you make any changes you need in transit:
var arrayLikeObject = {
length: 3,
name: 'thing',
'1': 'hello'
};
var array = Array.from(arrayLikeObject,
(element,index) => element?element.toUpperCase():`Item ${index}`
);
console.log(array);
There is also a performance difference. In this video Mathias Bynens recommends to use array over array-like-object because V8 is optimized for common arrays.
I think, in ES6, something is Array-like if it is iterable (has a [Symbol.iterator]
property).
{ length: 5}
is an array-like object but not an iterable. –
Seclusion © 2022 - 2024 — McMap. All rights reserved.
for
loop and number indices. Array-like objects are returned from many native DOM methods likegetElementsByClassName()
. – LisandralisbethforEach
method for example (it doesn't mean that). Clarifying which characteristics make an object array-like is good :) – Retrenchment