Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing things in objects vs arrays in JavaScript

This is more of a general question than a problem I need solved. I'm just a beginner trying to understand the proper way to do things.

What I want to know is whether or not I should only use objects as prototypes (if that's the correct term to use here) or whether or not it's OK to use them to store things.

As an example, in the test project I'm working on, I wanted to store some images for use later. What I currently have is something like:

var Images = {
    james: "images/james.png",
    karen: "images/karen.png",
    mike: "images/mike.png"
};

Because I would know the position, I figure I could also put them in an array and reference the position in the array appropriately:

var images = ["images/james.png", "images/karen.png", "images/mike.png"];
images[0];

Using the object like this works perfectly fine but I'm wondering which is the more appropriate way to do this. Is it situational? Are there any performance reasons to do one over the other? Is there a more accepted way that, as a new programmer, I should get used to?

Thanks in advance for any advice.

like image 997
AGx-07_162 Avatar asked May 01 '17 17:05

AGx-07_162


People also ask

Why is it better to use objects instead of arrays?

TL;DR Intro. Think about what your particular data represents: If it's a single entity with named properties, you want an object. If it's a group of entities of the same type/shape, or if order matters, you likely want an array.

What is the difference between arrays and objects in JavaScript?

In JavaScript, arrays use numbered indexes. In JavaScript, objects use named indexes.

Which is better array or objects?

The short version: Arrays are mostly faster than objects.

Can you store objects in an array JavaScript?

With an array, you store a collection of elements you can access by their position (or index). Objects take that concept further by providing a way to structure related data that's easy to read and retrieve using key/value pairs. It's common to combine the two by creating an array of objects.


1 Answers

Introduction

Unlike PHP, JavaScript does not have associative arrays. The two main data structures in this language are the array literal ([]) and the object literal ({}). Using one or another is not really a matter of style but a matter of need, so your question is relevant.

Let's make an objective comparison...

Array > Object

  1. An array literal (which is indirectly an object) has much more methods than an object literal. Indeed, an object literal is a direct instance of Object and has only access to Object.prototype methods. An array literal is an instance of Array and has access, not only to Array.prototype methods, but also to Object.prototype ones (this is how the prototype chain is set in JavaScript).

let arr = ['Foo', 'Bar', 'Baz'];
let obj = {foo: 'Foo', bar: 'Bar', baz: 'Baz'};

console.log(arr.constructor.name);
console.log(arr.__proto__.__proto__.constructor.name);

console.log(obj.constructor.name);
  1. In ES6, object literals are not iterable (according to the iterable protocol). But arrays are iterable. This means that you can use a for...of loop to traverse an array literal, but it will not work if you try to do so with an object literal (unless you define a [Symbol.iterator] property).

let arr = ['Foo', 'Bar', 'Baz'];
let obj = {foo: 'Foo', bar: 'Bar', baz: 'Baz'};

// OK
for (const item of arr) {
  console.log(item);
}

// TypeError
for (const item of obj) {
  console.log(item);
}

If you want to make an object literal iterable, you should define the iterator yourself. You could do this using a generator.

let obj = {foo: 'Foo', bar: 'Bar', baz: 'Baz'};

obj[Symbol.iterator] = function* () {
  yield obj.foo;
  yield obj.bar;
  yield obj.baz;
};

// OK
for (const item of obj) {
  console.log(item);
}

Array < Object

  1. An object literal is better than an array if, for some reason, you need descriptive keys. In arrays, keys are just numbers, which is not ideal when you want to create an explicit data model.

// This is meaningful
let me = {
  firstname: 'Baptiste',
  lastname: 'Vannesson',
  nickname: 'Bada',
  username: 'Badacadabra'
};

console.log('First name:', me.firstname);
console.log('Last name:', me.lastname);

// This is ambiguous
/*
   let me = ['Baptiste', 'Vannesson', 'Bada', 'Badacadabra'];
   
   console.log('First name:', me[0]);
   console.log('Last name:', me[1]);
*/
  1. An object literal is extremely polyvalent, an array is not. Object literals make it possible to create "idiomatic" classes, namespaces, modules and much more...

let obj = {
  attribute: 'Foo',
  method() {
    return 'Bar';
  },
  [1 + 2]: 'Baz'
};

console.log(obj.attribute, obj.method(), obj[3]);

Array = Object

  1. Array literals and object literals are not enemies. In fact, they are good friends if you use them together. The JSON format makes intensive use of this powerful friendship:

let people = [
  {
    "firstname": "Foo",
    "lastname": "Bar",
    "nicknames": ["foobar", "barfoo"] 
  },
  {
    "firstName": "Baz",
    "lastname": "Quux",
    "nicknames": ["bazquux", "quuxbaz"]
  }
];

console.log(people[0].firstname);
console.log(people[0].lastname);
console.log(people[1].nicknames[0]);
  1. In JavaScript, there is a hybrid data structure called array-like object that is extensively used, even though you are not necessarily aware of that. For instance, the good old arguments object within a function is an array-like object. DOM methods like getElementsByClassName() return array-like objects too. As you may imagine, an array-like object is basically a special object literal that behaves like an array literal:

let arrayLikeObject = {
  0: 'Foo',
  1: 'Bar',
  2: 'Baz',
  length: 3 
};

// At this level we see no difference...
for (let i = 0; i < arrayLikeObject.length; i++) {
  console.log(arrayLikeObject[i]);
}

Conclusion

Array literals and object literals have their own strengths and weaknesses, but with all the information provided here, I think you can now make the right decision.

Finally, I suggest you to try the new data structures introduced by ES6: Map, Set, WeakMap, WeakSet. They offer lots of cool features, but detailing them here would bring us too far...

like image 160
Badacadabra Avatar answered Sep 19 '22 18:09

Badacadabra