Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 1115495 of JavaScript object basics

  • Revision slug: Learn/JavaScript/Objects/Basics
  • Revision title: Introduction to objects
  • Revision id: 1115495
  • Created:
  • Creator: chrisdavidmills
  • Is current revision? No
  • Comment Learn/JavaScript/Objects/Introduction Learn/JavaScript/Objects/Basics

Revision Content

{{LearnSidebar}}
{{NextMenu("Learn/JavaScript/Object-oriented/Advanced", "Learn/JavaScript/Object-oriented")}}

In the first article looking at Object-oriented JavaScript (OOJS), we'll look at the theory of general object-oriented programming, and how this appears in JavaScript. Along the way we'll explain JavaScript object syntax, and revisit some JavaScript features we've already looked at earlier on in the course, reiterating the fact that many of the features you've already dealt with are in fact objects.

Prerequisites: Basic computer literacy, a basic understanding of HTML and CSS, familiarity with JavaScript basics (see First steps and Building blocks).
Objective: To understand the basic theory behind object-oriented programming, how this relates to JavaScript ("most things are objects"), and how to start working with JavaScript objects.

Object-oriented programming from 10,000 meters

To start with, let's give you a simplistic, high-level view of what Object-oriented programming (OOP) is. We say simplistic, because OOP can quickly get very complicated, and giving it a full treatment now would probably confuse more than help. The basic idea of OOP is that we use objects to model real world things that we want to represent inside our programs, and/or provide a simple way to access functionality that would otherwise be hard or impossible to make use of.

Objects can contain related data and code, which represent information about the thing you are trying to model, and functionality or behaviour that you want it to have. Object data and code is stored neatly (the official word is encapsulated) inside an object package (sometimes called a namespace), making it easy to structure and access.

Defining an object template

Let's consider a simple program that displays information about the students and teachers at a school. To start this off, we could create an object type called Person, which defines the generic data and functionality of a person. There are lots of things you could know about a person (their address, height, shoesize, DNA profile, passport number, significant personality traits ...) , but in this case we are only interested in showing their name, age, gender, and interests, and we also want to be able to write a short introduction about them based on this data, and get them to say hello. This is known as abstraction — creating a simple model of a more complex thing that is easy to work with for our program's purposes.

[INSERT PERSON DIAGRAM]

In OOP, this generic object type definition is called a class — it isn't actually an object, rather it is a template that defines what characteristics an object should have.

Creating actual objects

From our class, we can create object instances — objects that contain the data and functionality defined in the class. From our Person class, we can now create some actual people:

[INSERT DIAGRAM SHOWING PEOPLE OBJECTS BEING CREATED FROM CLASS]

When an object instance is created from a class, the class's constructor function is run to create it. This process of creating an object instance from a class is called instantiation — the object instance is instantiated from the class.

Specialist classes

But we don't want generic people — we want teachers and students, which are both more specific types of people. In OOP, we can create new classes based on other classes — these new child classes automatically inherit the data and code features of their parent class, but we can also give them specialized features of their own.

[SHOW INHERITANCE DIAGRAM, CREATING A TEACHER AND STUDENT CLASS FROM THE PERSON CLASS]

This is really useful — teachers and students share many common features such as name, gender, and age, so it is convenient to only have to define those features once. You can also define the same feature separately in different classes, as each definition of that feature will be in a different namespace. For example, a student's greeting might be of the form "Yo, I'm [firstName]" (e.g Hi, I'm Sam), whereas a teacher might use something more formal, such as "Hello, my name is [Prefix] [lastName]" (e.g Hello, My name is Mr Griffiths).

Note: The fancy word for the ability of multiple object types to implement the same functionality is polymorphism. Just in case you were wondering.

You can now create object instances from your child classes. For example:

[INSERT DIAGRAM SHOWING TEACHER AND STUDENT OBJECTS BEING CREATED FROM CLASSES]

Active learning: OOP in JavaScript

So far we've given you a very basic idea of OOP theory, but we've not shown how this translates into code. Let's move forward and work through implementing the above example in JavaScript!

To begin with, make a local copy of our oojs.html file. This contains very little — a {{htmlelement("script")}} element for us to write our code into, an {{htmlelement("input")}} element for us to enter code into, a few variable definitions, and a function that outputs any code entered into the input into a {{htmlelement("p")}} element.

Object basics

As with many things in JavaScript, creating an object often begins with defining and initializing a variable. Try entering the following below the JavaScript code that's already in your file, then saving and refreshing:

var person = {};

If you enter person into your text input and press the button, you should get the following result:

[object Object]

Congratulations, you've just created your first object. Job done! But this an empty object, so we can't really do much with it. Let's update our object to look like this:

var person = {
  name : ['Bob', 'Smith'],
  age : 32,
  gender : 'male',
  interests : ['music', 'skiing'],
  bio : function() {
    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  },
  greeting: function() {
    alert('Hi! I\'m ' + this.name[0] + '.');
  }
};

After saving and refreshing, try entering some of the following into your text input:

person.name[0]
person.age
person.interests[1]
person.bio()
person.greeting()

You have now got some data and functionality inside your object, are now able to access them with some nice simple syntax!

Note: If you are having trouble getting this to work, try comparing your code against our version — see oojs-finished.html (also see it running live). One common mistake when you are starting out with objects is to put a comma on the end of the last member — this will cause an error.

So what is going on here? Well, an object is made up of multiple members, each of which have a name (e.g. name and age above), and a value (e.g. ['Bob', 'Smith'] and 32). Each name/value pair must be separated by a comma, and the name and value in each case are separated by a colon. The syntax always follows this pattern:

var objectName = {
  member1Name : member1Value,
  member2Name : member2Value,
  member3Name : member3Value
}

The value of an object member can be pretty much anything — in our person object we've got a string, a number, two arrays, and two functions. The first four items are data items, and are referred to as the object's properties. The last two items are functions that allow the object to do something with that data, and are referred to as the object's methods.

An object like this is referred to as an object literal — we've literally written out the object contents as we've come to create it. This is in contrast to objects instantiated from classes, which we'll look at later on. It is very commmon to create an object literal when you want to transfer a series of structured, related data items in some manner, for example sent in a request to the server to be put into a database. Sending a single object is much more efficient than sending the items individually, and easier to work with than an array.

Dot notation

Above, you accessed the object's properties and methods using dot notation. The object name (person) acts as the namespace — it must be entered first to access anything encapsulated inside the object. then you write a dot, then the item you want to access — this can be the name of a simple property, an item of an array property, or a call to one of the object's methods, for example:

person.age
person.interests[1]
person.bio()

It is even possible to make the value of an object member another object. For example, try changing the name member from

name : ['Bob', 'Smith'],

to

name : {
  first : 'Bob',
  last : 'Smith'
},

Here we are effectively creating a sub-namespace. This sounds complex, but really it's not — to access these items you just need to chain the extra step onto the end with another dot. Try these:

person.name.first
person.name.last

Important: At this point you'll also need to go through your method code and change any instances of

name[0]
name[1]

to

name.first
name.last

Otherwise your methods will no longer work.

Bracket notation

There is another way to access object properties — using bracket notation. Instead of using these:

person.age
person.name.first

You can use

person['age']
person['name']['first']

This looks very similar to how you access the items in an array, and it is basically the same thing — instead of using an index number to select an item, you are using the name associated with each member's value. It is no wonder that objects are sometimes called associative arrays — they map strings to values in the same way that arrays map numbers to values.

Setting object members

So far we've only looked at retrieving (or getting) object members — you can also set (update) the value of object members by simply declaring the member you want to set (using dot or bracket notation), like this:

person.age = 45
person['name']['last'] = 'Cratchit'

Try entering these lines, and then getting the members again to see how they've changed:

person.age
person['name']['last']

Setting members doesn't just stop at updating the values of existing properties and methods; you can also create completely new members. Try these:

person['eyes'] = 'hazel'
person.farewell = function() { alert("Bye everybody!") }

You can now test out your new members:

person['eyes']
person.farewell()

One useful aspect of bracket notation is that it can be used to set not only member values dynamically, but member names too. Let's say we wanted users to be able to store custom value types in their people data, by typing the member name and value into two text inputs? We could get those values like this:

var myDataName = nameInput.value
var myDataValue = nameValue.value

we could then add this new member name and value to the person object like this:

person[myDataName] = myDataValue

To test this, try adding the following lines into your code, just below the closing curly brace of the person object:

var myDataName = 'height'
var myDataValue = '1.75m'
person[myDataName] = myDataValue

Now try saving and refreshing, and entering the following into your text input:

person.height

This isn't possible with dot notation, which can only accept a literal member name, not a variable value pointing to a name.

What is "this"?

You may have noticed something slightly strange in our methods. Look at this one for example:

greeting: function() {
  alert('Hi! I\'m ' + this.name.first + '.');
}

You are probably wondering what "this" is. The this keyword refers to the current object the code is being written inside — so in this case this is equivalent to person. So why not just write person instead? As you'll see in the next section when we start creating classes, etc., this is very useful — it is essential in constructors, and it will always ensure that the correct values are used when a member's context changes (e.g. two different person instances may have different names, and will want to use their own name when saying their greeting). Things will become clearer below.

Classes and object instances

What we've got so far makes sense. We've got an object that we can get and set properties and methods on. But what about all the stuff we said earlier, about creating classes and constructing object instances from classes?

First of all, we'd like you to make a new local copy of the oojs.html file — call it something different so you can distinguish the two.

A simple example

Inside your new file, add the following below the existing code:

function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

This is a constructor function, which defines an object class. You'll notice that it has all the features you'd expect in a function, but it doesn't return anything — it basically just defines properties and methods. You'll see the this keyword being used here as well — it is basically saying that whenever one of the these objects is instantiated, the object's name property will be equal to the name value passed to the constructor, and the greeting() method will use the name value passed to the constructor too.

Note: A constructor function name usually starts with a capital letter — this convention is used to make constructor functions easy to recognise in code.

So what does it look like when we call a constructor to instantiate some objects? Add the following lines below your previous code addition:

var person1 = new Person('Bob');
var person2 = new Person('Sarah');

Save your code and reload it in the browser, and try entering the following lines into your text input:

person1.name
person1.greeting()
person2.name
person2.greeting()

Cool! You'll now see that we have two new objects on the page, each of which have the name property and greeting() method available. But they are using their own name value that was assigned to them when they were instantiated; this is one reason why it is very important to use this, so they will use their own values, and not some other value.

Let's look at the constructor calls again:

var person1 = new Person('Bob');
var person2 = new Person('Sarah');

In each case, the new keyword is used to tell the browser we want to instantiate a new object instance, followed by the function name with its required parameters contained in parentheses, and the result is stored in a variable — very similar how to how a standard function is called. Each instance is created according to this class definition:

function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

After the new objects have been instantiated, the person1 and person2 variables effectively contain the following objects:

{
  name : 'Bob',
  greeting : function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

{
  name : 'Sarah',
  greeting : function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

We say effectively because in actual fact the function is still defined in the class, rather than in the object instances, in contrast to the object literal we looked at earlier.

Creating our finished constructor

The example we looked at above was only a simple example to get us started. Let's now get on and create our final Person constructor function. Remove the code you inserted so far, and add in this replacement constructor:

function Person(first, last, age, gender, interests) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interests = interests;
  this.bio = function() {
    alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  };
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name.first + '.');
  };
};

This is exactly the same as the simple example in principle, with just a bit more complexity.

Now add in the following line below it, to instantiate an object from it:

var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);

You'll now see that you can access the properties and methods just like we did with the first object we defined:

person1['age']
person1.interests[1]
person1.bio()
// etc.

Note: If you are having troubles getting this to work, try comparing your code against our version — see oojs-class-finished.html (also see it running live).

Further exercises

To start with, try adding a couple more object instantiation lines of your own, and try getting and setting the members of the resulting objects.

There are a couple of problems with our bio() method — the output always includes the pronoun "He", even if your person is female (or some other preferred gender classification). And the bio will only include two interests, even if more are listed in the interests array. Can you work out how to fix this in the class definition? You can put any code you like inside a class definition (you'll probably need a few conditionals and a loop). Think about how the sentences should be structured differently depending on gender, and depending on whether the number of listed interests is 1, 2, or more than 2.

Note: If you get stuck, we have provided an answer inside our GitHub repo (see it live) — try writing it yourself first though!

You've been using objects all along

As you've been going through some of these examples, you have probably been thinking that the dot notation you've been using is very familiar. That's because you've been using it throughout the course! Every time we've been working through an example that uses a built-in browser API or JavaScript object, we've been using objects, because such features are built using exactly the same kind of object structures that we've been looking at here, albeit more complex ones than our own custom examples.

So when you used string methods like:

myString.split(',');

You were using a method available on an instance of the String class. Every time you create a string in your code, that string is automatically created as an instance of String, and therefore has several common methods/properties available on it.

When you accessed the document object model using lines like this:

var myDiv = document.createElement('div');
var myVideo = document.querySelector('video');

You were using methods available on an instance of the Document class. For each webpage loaded, an instance of Document is created, called document, which represents the entire page's structure, content, and other features such as its URL. Again, this means that it has several common methods/properties available on it.

The same is true of pretty much any other built-in object/API you've been using — Array, Math, etc.

Note that built in Objects/APIs don't always create object instances automatically. As an example, the Notifications API — which allows modern browsers to fire system notifications — requires you to instantiate a new object instance using the constructor for each notification you want to fire. Try entering the following into your JavaScript console:

var myNotification = new Notification('Hello!');

Summary

Congratulations, you've reached the end of our first OOJS article — you should now have a good idea of what object-oriented programming is, how it relates to JavaScript, and how to work with objects in JavaScript — including creating your own simple objects. You should also appreciate that objects are very useful as structures for storing related data and functionality — if you tried to keep track of all the properties and methods in our person objects as separate variables and functions, it would be inefficient and frustrating, and we'd run the risk of clashing with other variables and functions that have the same names. Objects let us keep the information safely locked away in their own package, out of harm's way.

In the next article we'll finish up our coverage of JavaScript object concepts by looking at some items that we didn't get to in this article like inheritance, and other useful features besides.

{{NextMenu("Learn/JavaScript/Object-oriented/Build_your_own_object", "Learn/JavaScript/Object-oriented")}}

Revision Source

<div>{{LearnSidebar}}</div>

<div>{{NextMenu("Learn/JavaScript/Object-oriented/Advanced", "Learn/JavaScript/Object-oriented")}}</div>

<p class="summary">In the first article looking at Object-oriented JavaScript (OOJS), we'll look at the theory of general object-oriented programming, and how this appears in JavaScript. Along the way we'll explain JavaScript object syntax, and revisit some JavaScript features we've already looked at earlier on in the course, reiterating the fact that many of the features you've already dealt with are in fact objects.</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Prerequisites:</th>
   <td>Basic computer literacy, a basic understanding of HTML and CSS, familiarity with JavaScript basics (see <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>).</td>
  </tr>
  <tr>
   <th scope="row">Objective:</th>
   <td>To understand the basic theory behind object-oriented programming, how this relates to JavaScript ("most things are objects"), and how to start working with JavaScript objects.</td>
  </tr>
 </tbody>
</table>

<h2 id="Object-oriented_programming_from_10000_meters">Object-oriented programming from 10,000 meters</h2>

<p>To start with, let's give you a simplistic, high-level view of what Object-oriented programming (OOP) is. We say simplistic, because OOP can quickly get very complicated, and giving it a full treatment now would probably confuse more than help. The basic idea of OOP is that we use objects to model real world things that we want to represent inside our programs, and/or provide a simple way to access functionality that would otherwise be hard or impossible to make use of.</p>

<p>Objects can contain related data and code, which represent information about the thing you are trying to model, and functionality or behaviour that you want it to have. Object data and code is stored neatly (the official word is <strong>encapsulated</strong>) inside an object package (sometimes called a <strong>namespace</strong>), making it easy to structure and access.</p>

<h3 id="Defining_an_object_template">Defining an object template</h3>

<p>Let's consider a simple program that displays information about the students and teachers at a school. To start this off, we could create an object type called Person, which defines the generic data and functionality of a person. There are lots of things you <em>could</em> know about a person (their address, height, shoesize, DNA profile, passport number, significant personality traits ...) , but in this case we are only interested in showing their name, age, gender, and interests, and we also want to be able to write a short introduction about them based on this data, and get them to say hello. This is known as <strong>abstraction</strong> — creating a simple model of a more complex thing that is easy to work with for our program's purposes.</p>

<p>[INSERT PERSON DIAGRAM]</p>

<p>In OOP, this generic object type definition is called a <strong>class</strong> — it isn't actually an object, rather it is a template that defines what characteristics an object should have.</p>

<h3 id="Creating_actual_objects">Creating actual objects</h3>

<p>From our class, we can create <strong>object instances</strong> — objects that contain the data and functionality defined in the class. From our Person class, we can now create some actual people:</p>

<p>[INSERT DIAGRAM SHOWING PEOPLE OBJECTS BEING CREATED FROM CLASS]</p>

<p>When an object instance is created from a class, the class's <strong>constructor function</strong> is run to create it. This process of creating an object instance from a class is called <strong>instantiation</strong> — the object instance is <strong>instantiated</strong> from the class.</p>

<h3 id="Specialist_classes">Specialist classes</h3>

<p>But we don't want generic people — we want teachers and students, which are both more specific types of people. In OOP, we can create new classes based on other classes — these new <strong>child classes</strong> automatically <strong>inherit</strong> the data and code features of their <strong>parent class</strong>, but we can also give them specialized features of their own.</p>

<p>[SHOW INHERITANCE DIAGRAM, CREATING A TEACHER AND STUDENT CLASS FROM THE PERSON CLASS]</p>

<p>This is really useful — teachers and students share many common features such as name, gender, and age, so it is convenient to only have to define those features once. You can also define the same feature separately in different classes, as each definition of that feature will be in a different namespace. For example, a student's greeting might be of the form "Yo, I'm [firstName]" (e.g <em>Hi, I'm Sam</em>), whereas a teacher might use something more formal, such as "Hello, my name is [Prefix] [lastName]" (e.g <em>Hello, My name is Mr Griffiths</em>).</p>

<div class="note">
<p><strong>Note</strong>: The fancy word for the ability of multiple object types to implement the same functionality is <strong>polymorphism</strong>. Just in case you were wondering.</p>
</div>

<p>You can now create object instances from your child classes. For example:</p>

<p>[INSERT DIAGRAM SHOWING TEACHER AND STUDENT OBJECTS BEING CREATED FROM CLASSES]</p>

<h2 id="Active_learning_OOP_in_JavaScript">Active learning: OOP in JavaScript</h2>

<p>So far we've given you a very basic idea of OOP theory, but we've not shown how this translates into code. Let's move forward and work through implementing the above example in JavaScript!</p>

<p>To begin with, make a local copy of our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> file. This contains very little — a {{htmlelement("script")}} element for us to write our code into, an {{htmlelement("input")}} element for us to enter code into, a few variable definitions, and a function that outputs any code entered into the input into a {{htmlelement("p")}} element.</p>

<h3 id="Object_basics">Object basics</h3>

<p>As with many things in JavaScript, creating an object often begins with defining and initializing a variable. Try entering the following below the JavaScript code that's already in your file, then saving and refreshing:</p>

<pre class="brush: js">
var person = {};</pre>

<p>If you enter <code>person</code> into your text input and press the button, you should get the following result:</p>

<pre>
[object Object]</pre>

<p>Congratulations, you've just created your first object. Job done! But this an empty object, so we can't really do much with it. Let's update our object to look like this:</p>

<pre>
var person = {
  name : ['Bob', 'Smith'],
  age : 32,
  gender : 'male',
  interests : ['music', 'skiing'],
  bio : function() {
    alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  },
  greeting: function() {
    alert('Hi! I\'m ' + this.name[0] + '.');
  }
};
</pre>

<p>After saving and refreshing, try entering some of the following into your text input:</p>

<pre class="brush: js">
person.name[0]
person.age
person.interests[1]
person.bio()
person.greeting()</pre>

<p>You have now got some data and functionality inside your object, are now able to access them with some nice simple syntax!</p>

<div class="note">
<p><strong>Note</strong>: If you are having trouble getting this to work, try comparing your code against our version — see <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (also <a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">see it running live</a>). One common mistake when you are starting out with objects is to put a comma on the end of the last member — this will cause an error.</p>
</div>

<p>So what is going on here? Well, an object is made up of multiple members, each of which have a name (e.g. <code>name</code> and <code>age</code> above), and a value (e.g. <code>['Bob', 'Smith']</code> and <code>32</code>). Each name/value pair must be separated by a comma, and the name and value in each case are separated by a colon. The syntax always follows this pattern:</p>

<pre>
var objectName = {
  member1Name : member1Value,
  member2Name : member2Value,
  member3Name : member3Value
}</pre>

<p>The value of an object member can be pretty much anything — in our person object we've got a string, a number, two arrays, and two functions. The first four items are data items, and are referred to as the object's <strong>properties</strong>. The last two items are functions that allow the object to do something with that data, and are referred to as the object's <strong>methods</strong>.</p>

<p>An object like this is referred to as an <strong>object literal</strong> — we've literally written out the object contents as we've come to create it. This is in contrast to objects instantiated from classes, which we'll look at later on. It is very commmon to create an object literal when you want to transfer a series of structured, related data items in some manner, for example sent in a request to the server to be put into a database. Sending a single object is much more efficient than sending the items individually, and easier to work with than an array.</p>

<h4 id="Dot_notation">Dot notation</h4>

<p>Above, you accessed the object's properties and methods using <strong>dot notation</strong>. The object name (person) acts as the <strong>namespace</strong> — it must be entered first to access anything <strong>encapsulated</strong> inside the object. then you write a dot, then the item you want to access — this can be the name of a simple property, an item of an array property, or a call to one of the object's methods, for example:</p>

<pre class="brush: js">
person.age
person.interests[1]
person.bio()</pre>

<p>It is even possible to make the value of an object member another object. For example, try changing the name member from</p>

<pre class="brush: js">
name : ['Bob', 'Smith'],</pre>

<p>to</p>

<pre class="brush: js">
name : {
  first : 'Bob',
  last : 'Smith'
},</pre>

<p>Here we are effectively creating a <strong>sub-namespace</strong>. This sounds complex, but really it's not — to access these items you just need to chain the extra step onto the end with another dot. Try these:</p>

<pre class="brush: js">
person.name.first
person.name.last</pre>

<p><strong>Important</strong>: At this point you'll also need to go through your method code and change any instances of</p>

<pre class="brush: js">
name[0]
name[1]</pre>

<p>to</p>

<pre class="brush: js">
name.first
name.last</pre>

<p>Otherwise your methods will no longer work.</p>

<h4 id="Bracket_notation">Bracket notation</h4>

<p>There is another way to access object properties — using bracket notation. Instead of using these:</p>

<pre class="brush: js">
person.age
person.name.first</pre>

<p>You can use</p>

<pre class="brush: js">
person['age']
person['name']['first']</pre>

<p>This looks very similar to how you access the items in an array, and it is basically the same thing — instead of using an index number to select an item, you are using the name associated with each member's value. It is no wonder that objects are sometimes called <strong>associative arrays</strong> — they map strings to values in the same way that arrays map numbers to values.</p>

<h4 id="Setting_object_members">Setting object members</h4>

<p>So far we've only looked at retrieving (or <strong>getting</strong>) object members — you can also <strong>set</strong> (update) the value of object members by simply declaring the member you want to set (using dot or bracket notation), like this:</p>

<pre class="brush: js">
person.age = 45
person['name']['last'] = 'Cratchit'</pre>

<p>Try entering these lines, and then getting the members again to see how they've changed:</p>

<pre class="brush: js">
person.age
person['name']['last']</pre>

<p>Setting members doesn't just stop at updating the values of existing properties and methods; you can also create completely new members. Try these:</p>

<pre class="brush: js">
person['eyes'] = 'hazel'
person.farewell = function() { alert("Bye everybody!") }</pre>

<p>You can now test out your new members:</p>

<pre class="brush: js">
person['eyes']
person.farewell()</pre>

<p>One useful aspect of bracket notation is that it can be used to set not only member values dynamically, but member names too. Let's say we wanted users to be able to store custom value types in their people data, by typing the member name and value into two text inputs? We could get those values like this:</p>

<pre class="brush: js">
var myDataName = nameInput.value
var myDataValue = nameValue.value</pre>

<p>we could then add this new member name and value to the <code>person</code> object like this:</p>

<pre class="brush: js">
person[myDataName] = myDataValue</pre>

<p>To test this, try adding the following lines into your code, just below the closing curly brace of the <code>person</code> object:</p>

<pre class="brush: js">
var myDataName = 'height'
var myDataValue = '1.75m'
person[myDataName] = myDataValue</pre>

<p>Now try saving and refreshing, and entering the following into your text input:</p>

<pre class="brush: js">
person.height</pre>

<p>This isn't possible with dot notation, which can only accept a literal member name, not a variable value pointing to a name.</p>

<h4 id="What_is_this">What is "this"?</h4>

<p>You may have noticed something slightly strange in our methods. Look at this one for example:</p>

<pre class="brush: js">
greeting: function() {
  alert('Hi! I\'m ' + this.name.first + '.');
}</pre>

<p>You are probably wondering what "this" is. The <code>this</code> keyword refers to the current object the code is being written inside — so in this case <code>this</code> is equivalent to <code>person</code>. So why not just write <code>person</code> instead? As you'll see in the next section when we start creating classes, etc., <code>this</code> is very useful — it is essential in constructors, and it will always ensure that the correct values are used when a member's context changes (e.g. two different person instances may have different names, and will want to use their own name when saying their greeting). Things will become clearer below.</p>

<h3 id="Classes_and_object_instances">Classes and object instances</h3>

<p>What we've got so far makes sense. We've got an object that we can get and set properties and methods on. But what about all the stuff we said earlier, about creating classes and constructing object instances from classes?</p>

<p>First of all, we'd like you to make a new local copy of the <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> file — call it something different so you can distinguish the two.</p>

<h4 id="A_simple_example">A simple example</h4>

<p>Inside your new file, add the following below the existing code:</p>

<pre class="brush: js">
function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}</pre>

<p>This is a <strong>constructor</strong> function, which defines an object <strong>class</strong>. You'll notice that it has all the features you'd expect in a function, but it doesn't return anything — it basically just defines properties and methods. You'll see the <code>this</code> keyword being used here as well — it is basically saying that whenever one of the these objects is instantiated, the object's <code>name</code> property will be equal to the name value passed to the constructor, and the <code>greeting()</code> method will use the name value passed to the constructor too.</p>

<div class="note">
<p><strong>Note</strong>: A constructor function name usually starts with a capital letter — this convention is used to make constructor functions easy to recognise in code.</p>
</div>

<p>So what does it look like when we call a constructor to instantiate some objects? Add the following lines below your previous code addition:</p>

<pre class="brush: js">
var person1 = new Person('Bob');
var person2 = new Person('Sarah');</pre>

<p>Save your code and reload it in the browser, and try entering the following lines into your text input:</p>

<pre class="brush: js">
person1.name
person1.greeting()
person2.name
person2.greeting()</pre>

<p>Cool! You'll now see that we have two new objects on the page, each of which have the <code>name</code> property and <code>greeting()</code> method available. But they are using their own <code>name</code> value that was assigned to them when they were instantiated; this is one reason why it is very important to use <code>this</code>, so they will use their own values, and not some other value.</p>

<p>Let's look at the constructor calls again:</p>

<pre class="brush: js">
var person1 = new Person('Bob');
var person2 = new Person('Sarah');</pre>

<p>In each case, the <code>new</code> keyword is used to tell the browser we want to instantiate a new object instance, followed by the function name with its required parameters contained in parentheses, and the result is stored in a variable — very similar how to how a standard function is called. Each instance is created according to this class definition:</p>

<pre class="brush: js">
function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}</pre>

<p>After the new objects have been instantiated, the <code>person1</code> and <code>person2</code> variables effectively contain the following objects:</p>

<pre class="brush: js">
{
  name : 'Bob',
  greeting : function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

{
  name : 'Sarah',
  greeting : function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}</pre>

<p>We say effectively because in actual fact the function is still defined in the class, rather than in the object instances, in contrast to the object literal we looked at earlier.</p>

<h4 id="Creating_our_finished_constructor">Creating our finished constructor</h4>

<p>The example we looked at above was only a simple example to get us started. Let's now get on and create our final <code>Person</code> constructor function. Remove the code you inserted so far, and add in this replacement constructor:</p>

<pre class="brush: js">
function Person(first, last, age, gender, interests) {
  this.name = {
    first,
    last
  };
  this.age = age;
  this.gender = gender;
  this.interests = interests;
  this.bio = function() {
    alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
  };
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name.first + '.');
  };
};</pre>

<p>This is exactly the same as the simple example in principle, with just a bit more complexity.</p>

<p>Now add in the following line below it, to instantiate an object from it:</p>

<pre class="brush: js">
var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre>

<p>You'll now see that you can access the properties and methods just like we did with the first object we defined:</p>

<pre class="brush: js">
person1['age']
person1.interests[1]
person1.bio()
// etc.</pre>

<div class="note">
<p><strong>Note</strong>: If you are having troubles getting this to work, try comparing your code against our version — see <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (also <a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">see it running live</a>).</p>
</div>

<h4 id="Further_exercises">Further exercises</h4>

<p>To start with, try adding a couple more object instantiation lines of your own, and try getting and setting the members of the resulting objects.</p>

<p>There are a couple of problems with our <code>bio()</code> method — the output always includes the pronoun "He", even if your person is female (or some other preferred gender classification). And the bio will only include two interests, even if more are listed in the <code>interests</code> array. Can you work out how to fix this in the class definition? You can put any code you like inside a class definition (you'll probably need a few conditionals and a loop). Think about how the sentences should be structured differently depending on gender, and depending on whether the number of listed interests is 1, 2, or more than 2.</p>

<div class="note">
<p><strong>Note</strong>: If you get stuck, we have provided an <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">answer inside our GitHub repo</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">see it live</a>) — try writing it yourself first though!</p>
</div>

<h2 id="You've_been_using_objects_all_along">You've been using objects all along</h2>

<p>As you've been going through some of these examples, you have probably been thinking that the dot notation you've been using is very familiar. That's because you've been using it throughout the course! Every time we've been working through an example that uses a built-in browser API or JavaScript object, we've been using objects, because such features are built using exactly the same kind of object structures that we've been looking at here, albeit more complex ones than our own custom examples.</p>

<p>So when you used string methods like:</p>

<pre class="brush: js">
myString.split(',');</pre>

<p>You were using a method available on an instance of the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> class. Every time you create a string in your code, that string is automatically created as an instance of <code>String</code>, and therefore has several common methods/properties available on it.</p>

<p>When you accessed the document object model using lines like this:</p>

<pre class="brush: js">
var myDiv = document.createElement('div');
var myVideo = document.querySelector('video');</pre>

<p>You were using methods available on an instance of the <code><a href="/en-US/docs/Web/API/Document">Document</a></code> class. For each webpage loaded, an instance of <code>Document</code> is created, called <code>document</code>, which represents the entire page's structure, content, and other features such as its URL. Again, this means that it has several common methods/properties available on it.</p>

<p>The same is true of pretty much any other built-in object/API you've been using — <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code>, etc.</p>

<p>Note that built in Objects/APIs don't always create object instances automatically. As an example, the <a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a> — which allows modern browsers to fire system notifications — requires you to instantiate a new object instance using the constructor for each notification you want to fire. Try entering the following into your JavaScript console:</p>

<pre class="brush: js">
var myNotification = new Notification('Hello!');</pre>

<h2 id="Summary">Summary</h2>

<p>Congratulations, you've reached the end of our first OOJS article — you should now have a good idea of what object-oriented programming is, how it relates to JavaScript, and how to work with objects in JavaScript — including creating your own simple objects. You should also appreciate that objects are very useful as structures for storing related data and functionality — if you tried to keep track of all the properties and methods in our person objects as separate variables and functions, it would be inefficient and frustrating, and we'd run the risk of clashing with other variables and functions that have the same names. Objects let us keep the information safely locked away in their own package, out of harm's way.</p>

<p>In the next article we'll finish up our coverage of JavaScript object concepts by looking at some items that we didn't get to in this article like <em>inheritance</em>, and other useful features besides.</p>

<p>{{NextMenu("Learn/JavaScript/Object-oriented/Build_your_own_object", "Learn/JavaScript/Object-oriented")}}</p>
Revert to this revision