Javascript: Understanding Objects vs Arrays and When to Use Them

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 ((-1 * 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!