Javascript: Understanding Objects vs Arrays and When to Use Them. [Part 1]

See Part 2 here

What are Objects and how do they differ from Arrays in Javascript?
When is it advantageous to use one over the other?

I ran into this question several times while browsing through stackoverflow's javascript queue so I decided to recycle my answers, elaborate a bit and make it into a blog post. If you are new to javascript, understanding these two data types is very important and could potentially save you some headache down the road.

Declaration & Augmentation

Array(s):
  var myArray = new Array(); // Array constructor (try to avoid)
  // is the equivalent of:
  var myArray = []; // Array literal (preferred way)
  var anotherArray = [1, 5, "string", {hello: "world"}] // Array with some elements of mixed type

Arrays come with several, very useful native methods. We can add a new element to existing array instance using push() and remove the last element from the array via pop(). We can also use splice() to remove n elements and/or insert new element(s) at index i.

  myArray.push("this"); // push a string on the stack
  myArray.push("is", "neat", "!"); // push multiple comma separated elements, in this case 3 strings. 
 
  console.log(myArray); // prints ["this", "is", "neat", "!"]
 
  var a = myArray.pop(); // pops the last element from the stack
  console.log(a); // prints "!"
  console.log(myArray); // prints ["this", "is", "neat"]
 
  // remove n elements starting at index i from myArray, where i = 0 and n = 2 in this case.
  // splice(i, n, k0, k1, ..., kn) modifies myArray, returns spliced chunk as an array and optionally inserts k0-kn new elements at index i.
  var b = myArray.splice(0, 2); // not to be confused with slice()
  console.log(b); // prints ["this", "is"]
  console.log(myArray); // prints ["neat"]
 
  // we can also use splice to add new elements at index i
  myArray.splice(0, 0 ,"isn't", "this"); // remove n = 0 elements and insert "isn't" and "this" starting at index i = 0
  myArray.push("?"); // push "?" at the end of the stack
  console.log(myArray); // prints ["isn't", "this", "neat", "?"]
 
  // we could have done last two operations in one step by doing the following
  myArray = ["this", "is", "neat", "?"];
  myArray.splice(0, 2,"isn't", "this");
  console.log(myArray); // prints ["isn't", "this", "neat", "?"]

You can find out more about Arrays, their methods and properties at MDN.

Object(s):
  var myObject = new Object(); // Object constructor (try to avoid)
  // is the equivalent of:
  var myObject = {}; // Object literal (preferred way)

Think about objects as associative arrays, i.e. list of key -> value pairs.
These keys are referred to as object properties.
Follow this pattern when declaring new objects:

  // Note: each object property declaration is comma separated.
  // You don't need to prefix each object property like I did in the example below.
  // You can use any (read most) valid javascript strings as an object property.
  var myObject = {
    propertyString: "this is a string",
    propertyAnotherString: "this is another string",
    propertyMixedArray: ["item 1", "item 2", 1, 2, {}],
    // Note above, we have different data types in the array:
    // two strings, two ints/numbers and one empty object.
    // This is completely legal in javascript.
    propertyObject: { someProperty: "and so on..." }
  };

Javascript is a dynamic language. You are allowed to extend/augment objects and their prototype after object has been defined as well as during runtime.

  // Adding additional properties is OK too.
  // Note: this time we use "=" instead of ":" to assign value
  myObject.additionalProperty = "Additional property";
 
  // prints "this is a string"
  console.log(myObject.propertyString);
 
  // also prints "this is a string"
  // I'm treating object as an associative array or hashtable
  console.log(myObject["propertyString"]);
 
  // also prints "this is a string"
  // we can use variables as well to dynamically access keys.
  var keyFromVariable = "propertyString";
  console.log(myObject[keyFromVariable]);
 
  // Couple of other examples.
  console.log(myObject.propertyMixedArray[1]); // prints "item 2"
  console.log(myObject.propertyObject.someProperty); // prints "and so on..."
  console.log(myObject.additionalProperty); // prints "Additional property"

Deleting a property is very simple:

  var newObj = {
    foo: "here be dragons",
    bar: "foo is a lie"
  };
  delete newObj.bar; // is the equivalent of delete newObj['bar'];
  console.log(newObj); // prints Object {foo: "here be dragons"}

Javascript community prefers using literal notation as it makes the code cleaner and easier to understand. Whether you decide to go with literal declaration or using constructors, be consistent. Read more about Objects on MDN.

Checking if Property or Value Exists

Array(s):

Generally when we work with arrays, we care less about indexes and more about values.
One of the common operations we perform with Arrays is checking if a certain value is in the array.
This is easily accomplished using indexOf() method.

  var testArr = [1, 4, 3, 0, "sticks", 3, "foo"];
 
  // Check if there is at least one instance of number 3 in testArr;
  var i = testArr.indexOf(3); // value of i will be 2 as that is where the first instance of number 3 is located
  var nope = testArr.indexOf("jetpack"); // value of nope will be -1 since testArr doesn't contain a string "jetpack"
  // Note: testArr.indexOf(value) will return an integer between 0 and (testArr.length-1) if value exists
  // or -1 if value is not found in the array.
 
  // This will print 'Woo hoo!' since 3 is in testArr;
  if (i != -1) {
    console.log('Woo hoo!');
  } else {
    console.log('Bummer!');
  }
 
  // Alternatively to checking if (i > -1) or if (i != -1),
  // we could have done (I personally prefer this approach):
  if (~i) { // This is (~) tilda, NOT (-) dash/minus
    console.log('Woo hoo!');
  } else {
    console.log('Bummer!');
  }
  // or
  if (~testArr.indexOf(3)) { // This is (~) tilda, NOT (-) dash/minus
    console.log('Woo hoo!');
  } else {
    console.log('Bummer!');
  }

To find out more about Bitwise NOT (~) operator and why it works in this scenario, check out the good ole MDN.

Object(s):

In contrast to Arrays, we generally want to know if an Object contains a certain property. Usually we will write a function that takes Object as an argument and will expect that it contains a certain set of properties. This Object can come from an API or some other piece of code and we shouldn't rely on it having all the properties we expect. It is always a good idea to check whether the property exists before accessing the value behind that property. Objects come with hasOwnProperty() method which allows us to do just that.

  var testObj = {
    foo: "tball"
  };
 
  // prints: 'We got ourselves a foo!'
  if (testObj.hasOwnProperty('foo')) {
    console.log('We got ourselves a foo!');
  } else {
    console.log('No foo for you!');
  }
 
  // prints: Too drunk, cannot locate the bar. Football at my place! 
  if (testObj.hasOwnProperty('bar')) {
    console.log('We are at the bar, watching the football game');
  } else {
    console.log('Too drunk, cannot locate the bar. Football at my place!');
  }

Ok folks, I have a confession to make. I was not entirely honest with you. There is a "small" detail that I have purposefully omitted when comparing these two data types. Read Part 2 of this post to find out more!

Filed under:

Comments

Iteration and structure comparison is covered in Part 2 of the post.

 

To summarize, Arrays are really good at storing ordered lists and ordering things while the cost of removing/splicing elements is a bit higher. Objects are great at representing schemas and the cost of augmenting or deleting properties is very low, but are not good for preserving order. When working with JSON API endpoints that return list of items, you will generally be working with Arrays of Objects.

it is true that "hash tables" don't have order, but JavaScript objects do have order. To convince yourself this is this is the case, add entries into an object one at a time and then enumerate the keys. The result will be that the order is preserved. This can be a bit tricky to reason about when dealing with JSON, since if you choose to store data in an object, it can be tricky to decide how to "sort" an object. Strangely, moving random key, value pairs to a new object one by one works, but it's odd considering it's based on an unordered collection.

That may be true where you tried it but you have to remember that the construct does not guarantee that, so you may see different behaviours in different browsers and possibly from one version to the next.

So, even if it is true right now, you can't bank on it.

Long story short, if you need a specific sequence of keys, you have to use arrays.

Hey, thanks Slavko - for someone learning the difference, I found this by searching for a definition of objects vs arrays and object literals. Nice explanation and clear code examples. Very helpful.

A nice additional example would be on how to add an element to an object where both the name and the value are passed in strings:

myObject["someString"] = "yeah!"

Passing the key as a bracket-notated string, according to
this SO article: http://stackoverflow.com/questions/4968406/javascript-property-access-d… which cites
this article: http://www.dev-archive.net/articles/js-dot-notation/
"Square bracket notation allows use of characters that can't be used with dot notation"

I don't have any real opinion on the topic outside wanting to point out these things I'd read, and to say thanks Slavo for the insights!

I work in Chinatown -- maybe I'll drop by to check out Metal Toad.
Thanks again!

Thnak you, for such a simplicity of work, so that it was helpfull for me a lot. And, hope for other's too.
Keep it up:)

I'm learning Javascript and this article was exactly what I needed. Thanks!

With information scattered, this was helpful in solidifying knowledge which is essential for me to get started and really opens up possibilities to developers.

Nice! Thx for this detail!

I have been surfing online more than 3 hours today, yet I never found any interesting article like yours. It is pretty worth enough for me. In my view, if all webmasters and bloggers made good content as you did, the internet will be much more useful than ever before. defaeacegffcabed

Hi Slavko...Many thanks in advance :)

// If I have an array like below
var myArray=[];
myArray = [{"key": "1", "value" :"Orange"},{"key": "2", "value" :"Mango"}] ;

what is the difference if i write like below:

myArray.push({"key": "1", "value" :"Orange"});
myArray.push({"key": "2", "value" :"Mango"});

Thanks

Thanks for your article, Slavko!

http://stackoverflow.com/questions/12299665/what-does-a-tilde-do
Quoting the above url, regarding the tilde operator:

It's also less relevant now that JavaScript has Array.prototype.includes() and String.prototype.includes(). These return a boolean value. If your target platform(s) support it, you should prefer this for testing for the existence of a value in a string or array.

Can we add function and use it into object?

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <cpp>, <java>, <php>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Ready for transformation?