10 min read

(For more resources related to this topic, see here.)

An array is just a list of values. Each value has an index (a numeric key) that starts from zero and increments by one for each value.

> var myarr = ['red', 'blue', 'yellow', 'purple']; > myarr; ["red", "blue", "yellow", "purple"]. > myarr[0]; "red" > myarr[3]; "purple"

If you put the indexes in one column and the values in another, you’ll end up with a table of key/value pairs shown as follows:

Key

Value

0

red

1

blue

2

yellow

3

purple

An object is similar to an array, but with the difference that you define the keys yourself. You’re not limited to using only numeric indexes and you can use friendlier keys, such as first_name, age, and so on.

Let’s take a look at a simple object and examine its parts:

var hero = { breed: 'Turtle', occupation: 'Ninja' };

You can see that:

  • The name of the variable that refers to the object is hero
  • Instead of [ and ], which you use to define an array, you use { and } for objects
  • You separate the elements (called properties) contained in the object with commas
  • The key/value pairs are divided by colons, as in key: value

The keys (names of the properties) can optionally be placed in quotation marks. For example, these are all the same:

var hero = {occupation: 1}; var hero = {"occupation": 1}; var hero = {'occupation': 1};

It’s recommended that you don’t quote the names of the properties (it’s less typing), but there are cases when you must use quotes:

  • If the property name is one of the reserved words in JavaScript 
  • If it contains spaces or special characters (anything other than letters, numbers, and the _ and $ characters)
  • If it starts with a number

In other words, if the name you have chosen for a property is not a valid name for a variable in JavaScript, then you need to wrap it in quotes.

Have a look at this bizarre-looking object:

var o = { $omething: 1, 'yes or no': 'yes', '!@#$%^&*': true };

This is a valid object. The quotes are required for the second and the third properties, otherwise you’ll get an error.

Later in this chapter, you’ll see other ways to define objects and arrays in addition to [] and {}. But first, let’s introduce this bit of terminology: defining an array with [] is called array literal notation, and defining an object using the curly braces {} is called object literal notation.

Elements, properties, methods, and members

When talking about arrays, you say that they contain elements. When talking about objects, you say that they contain properties. There isn’t any significant difference in JavaScript; it’s just the terminology that people are used to, likely from other programming languages.

A property of an object can point to a function, because functions are just data. Properties that point to functions are also called methods. In the following example, talk is a method:

var dog = { name: 'Benji', talk: function () { alert('Woof, woof!'); } };

As you have seen in the previous chapter, it’s also possible to store functions as array elements and invoke them, but you’ll not see much code like this in practice:

> var a = []; > a[0] = function (what) { alert(what); }; > a[0]('Boo!');

You can also see people using the word members to refer to properties of an object, most often when it doesn’t matter if the property is a function or not.

Hashes and associative arrays

In some programming languages, there is a distinction between:

  • A regular array, also called an indexed or enumerated array (the keys are numbers)
  • An associative array, also called a hash or a dictionary (the keys are strings)

JavaScript uses arrays to represent indexed arrays and objects to represent associative arrays. If you want a hash in JavaScript, you use an object.

Accessing an object’s properties

There are two ways to access a property of an object:

  • Using the square bracket notation, for example hero[‘occupation’]
  • Using the dot notation, for example hero.occupation

The dot notation is easier to read and write, but it cannot always be used. The same rules apply as for quoting property names: if the name of the property is not a valid variable name, you cannot use the dot notation.

Let’s take the hero object again:

var hero = { breed: 'Turtle', occupation: 'Ninja' };

Accessing a property with the dot notation:

> hero.breed; "Turtle"

Accessing a property with the bracket notation:

> hero['occupation']; "Ninja"

Accessing a non-existing property returns undefined:

> 'Hair color is ' + hero.hair_color; "Hair color is undefined"

Objects can contain any data, including other objects:

var book = { name: 'Catch-22', published: 1961, author: { firstname: 'Joseph', lastname: 'Heller' } };

To get to the firstname property of the object contained in the author property of the book object, you use:

> book.author.firstname; "Joseph"

Using the square brackets notation:

> book['author']['lastname']; "Heller"

It works even if you mix both:

> book.author['lastname']; "Heller" > book['author'].lastname; "Heller"

Another case where you need square brackets is when the name of the property you need to access is not known beforehand. During runtime, it’s dynamically stored in a variable:

> var key = 'firstname'; > book.author[key]; "Joseph"

Calling an object’s methods

You know a method is just a property that happens to be a function, so you access methods the same way as you would access properties: using the dot notation or using square brackets. Calling (invoking) a method is the same as calling any other function: you just add parentheses after the method name, which effectively says “Execute!”.

> var hero = { breed: 'Turtle', occupation: 'Ninja', say: function () { return 'I am ' + hero.occupation; } }; > hero.say(); "I am Ninja"

If there are any parameters that you want to pass to a method, you proceed as with normal functions:

> hero.say('a', 'b', 'c');

Because you can use the array-like square brackets to access a property, this means you can also use brackets to access and invoke methods:

> hero['say']();

This is not a common practice unless the method name is not known at the time of writing code, but is instead defined at runtime:

var method = 'say'; hero[method]();

Best practice tip: no quotes (unless you have to)

Use the dot notation to access methods and properties and don’t quote properties in your object literals.

Altering properties/methods

JavaScript allows you to alter the properties and methods of existing objects at any time. This includes adding new properties or deleting them. You can start with a “blank” object and add properties later. Let’s see how you can go about doing this.

An object without properties is shown as follows:

> var hero = {};

A “blank” object

In this section, you started with a “blank” object, var hero = {};. Blank is in quotes because this object is not really empty and useless. Although at this stage it has no properties of its own, it has already inherited some. You’ll learn more about own versus inherited properties later. So, an object in ES3 is never really “blank” or “empty”. In ES5 though, there is a way to create a completely blank object that doesn’t inherit anything, but let’s not get ahead too much.

Accessing a non-existing property is shown as follows:

> typeof hero.breed; "undefined"

Adding two properties and a method:

> hero.breed = 'turtle'; > hero.name = 'Leonardo'; > hero.sayName = function () { return hero.name; };

Calling the method:

> hero.sayName(); "Leonardo"

Deleting a property:

> delete hero.name; true

Calling the method again will no longer find the deleted name property:

> hero.sayName(); "undefined"

Malleable objects

You can always change any object at any time, such as adding and removing properties and changing their values. But, there are exceptions to this rule. A few properties of some built-in objects are not changeable (for example, Math.PI, as you’ll see later).

Using the this value

In the previous example, the sayName() method used hero.name to access the name property of the hero object. When you’re inside a method though, there is another way to access the object the method belongs to: by using the special value this.

> var hero = { name: 'Rafaelo', sayName: function () { return this.name; } }; > hero.sayName(); "Rafaelo"

So, when you say this, you’re actually saying “this object” or “the current object”.

Constructor functions

There is another way to create objects: by using constructor functions. Let’s see an example:

function Hero() { this.occupation = 'Ninja'; }

In order to create an object using this function, you use the new operator, like this:

> var hero = new Hero(); > hero.occupation; "Ninja"

A benefit of using constructor functions is that they accept parameters, which can be used when creating new objects. Let’s modify the constructor to accept one parameter and assign it to the name property:

function Hero(name) { this.name = name; this.occupation = 'Ninja'; this.whoAreYou = function () { return "I'm " + this.name + " and I'm a " + this.occupation; }; }

Now you can create different objects using the same constructor:

> var h1 = new Hero('Michelangelo'); > var h2 = new Hero('Donatello'); > h1.whoAreYou(); "I'm Michelangelo and I'm a Ninja" > h2.whoAreYou(); "I'm Donatello and I'm a Ninja"

Best practice

By convention, you should capitalize the first letter of your constructor functions so that you have a visual clue that this is not intended to be called as a regular function.

If you call a function that is designed to be a constructor but you omit the new operator, this is not an error, but it doesn’t give you the expected result.

> var h = Hero('Leonardo'); > typeof h; "undefined"

What happened here? There is no new operator, so a new object was not created. The function was called like any other function, so h contains the value that the function returns. The function does not return anything (there’s no return), so it actually returns undefined , which gets assigned to h.

In this case, what does this refer to? It refers to the global object.

The global object

You have already learned a bit about global variables (and how you should avoid them). You also know that JavaScript programs run inside a host environment (the browser for example). Now that you know about objects, it’s time for the whole truth: the host environment provides a global object and all global variables are accessible as properties of the global object.

If your host environment is the web browser, the global object is called window. Another way to access the global object (and this is also true in most other environments) is to use this outside a constructor function, for example in the global program code outside any function.

As an illustration, you can declare a global variable outside any function, such as:

> var a = 1;

Then, you can access this global variable in various ways:

  • As a variable a
  • As a property of the global object, for example window[‘a’] or window.a
  • As a property of the global object referred to as this:

    > var a = 1; > window.a; 1 > this.a; 1

Let’s go back to the case where you define a constructor function and call it without the new operator. In such cases, this refers to the global object and all the properties set to this become properties of window.

Declaring a constructor function and calling it without new returns “undefined” :

> function Hero(name) { this.name = name; } > var h = Hero('Leonardo'); > typeof h; "undefined" > typeof h.name; TypeError: Cannot read property 'name' of undefined

Because you had this inside Hero, a global variable (a property of the global object) called name was created:

> name; "Leonardo" > window.name; "Leonardo"

If you call the same constructor function using new, then a new object is returned and this refers to it:

> var h2 = new Hero('Michelangelo'); > typeof h2; "object" > h2.name; "Michelangelo"

The built-in global functions can also be invoked as methods of the window object. So, the following two calls have the same result:

> parseInt('101 dalmatians'); 101 > window.parseInt('101 dalmatians'); 101

And, when outside a function called as a constructor (with new), also:

> this.parseInt('101 dalmatians'); 101

LEAVE A REPLY

Please enter your comment!
Please enter your name here