Creating array-like objects in JavaScript

Viewed 14239

In JavaScript, there are objects that pretend to be arrays (or are "array-like"). Such objects are arguments, NodeLists (returned from getElementsByClassName, etc.), and jQuery objects.

When console.logged, they appear as arrays, but they are not. I know that in order to be array-like, an object must have a length property.

So I made an "object" like this:

function foo(){
    this.length = 1;
    this[0] = "bar";
}

var test = new foo;

When I console log(test), I get (as expected) a foo object. I can "convert" it to an array using

Array.prototype.slice.call(test)

But, I don't want to convert it, I want it to be array-like. How do I make an array-like object, so that when it's console.logged, it appears as an array?

I tried setting foo.prototype = Array.prototype, but console.log(new foo) still shows a foo object, and not an array.

5 Answers

The same question got into my mind as while we can use array like arguments parameter:

function arrayLike() {
  console.log(typeof arguments)
  console.log(arguments)
  console.log(Array.from(arguments))
}
arrayLike(1,2,3)

So, let's try creating our own array-like object:

let arrayLikeObject = {
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))

Obviously, there's no length property defined so our arrayLikeObject will only return an empty array. Now, let's try defining a length property:

let arrayLikeObject = {
  length: 2,
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))

What if length is set different?

let arrayLikeObject = {
  length: 1,
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))
 // it will only return the value from first `0: 1`

let arrayLikeObject = {
  length: 5,
  0: 1,
  1: 2
 }
 
 console.log(Array.from(arrayLikeObject))
 // other 3 values will be printed as undefined


But, I don't want to convert it...

You actually wanted to create an array, not array-like object. The array-like object must be converted like you said:

Array.prototype.slice.call(arrayLikeObject)
// Or,
[].slice.call(arrayLikeObject)

If you do try to use array methods on array-like object, then you'll get type error:

let arrayLikeObject = {
  length: 5,
  0: 1,
  1: 2
 }

 console.log(arrayLikeObject.sort())

Thus, to use the array methods on arrayLikeObject, we need to convert it into array as we did in preceding examples using Array.from.

Otherwise, you simply need to create an array:

let arr = [1,2] // I don't mean, you don't know

Other consideration:

You can't use it as constructor:

let arrayLikeObject = {
    length: 1,
    slice: function () {
      return 1
    }
}

console.log(new arrayLikeObject) // Type error

In the following snippet, the result will be [undefined] as the length property is set to 1 but there's no 0 indexed property:

let arrayLikeObject = {
  length: 1,
  slice: function () {
    return 1
  }
}
console.log(Array.from(arrayLikeObject))

But if you set the length to 0, then the result will be an empty array [] because we're telling that we don't have any values in this array-like object.

Related