Creating Objects
JavaScript offers several ways to create an object. Let’s look first at how to declare a direct instance of an object; later we create an object by using a constructor function.
Create a Direct Instance
JavaScript has a built-in object simply called Object that you can use as a kind of blank canvas for creating your own objects:
myNewObject = new Object();
OK, you now have a brand new object, myNewObject. For the moment, it doesn’t actually do anything, as it doesn’t have any properties or methods. You can begin to rectify that by adding a property:
myNewObject.info = 'I am a shiny new object';
Now your object owns a property—in this case a text string containing some information about the object and called info. You can also easily add a method to the object too, by first defining a function, and then attaching it to myNewObject as one of the object’s methods:
function myFunc() { alert(this.info); }; myNewObject.showInfo = myFunc;
To call the new method, you can simply use the now-familiar dot notation:
myNewObject.showInfo();
Using the this Keyword
<img src="tick.gif" alt="tick" onmouseover="this.src='tick2.gif';" />
When used in that way, this refers to the HTML element itself—in the preceding case the <img> element. When you use this inside a function (or method), the keyword this refers to the function’s parent object.
Upon the first declaration of the function myFunc(), its parent is the global object; that is, the window object. The window object does not have a property called info, so if you were to call the myFunc() function directly, an error would occur.
However, you go on to create a method called showInfo of myNewObject and you assign myFunc() to that method:
myNewObject.showInfo = myFunc;
In the context of the showInfo() method, myNewObject is the parent object, so this.info refers to the property myNewObject.info.
<!DOCTYPE html> <html> <head> <title>Object Oriented Programming</title> <script> myNewObject = new Object(); myNewObject.info = 'I am a shiny new object'; function myFunc(){ alert(this.info); } myNewObject.showInfo = myFunc; </script> </head> <body> <input type="button" value="Good showInfo Call" onclick="myNewObject.showInfo()" /> <input type="button" value="myFunc Call" onclick="myFunc()" /> <input type="button" value="Bad showInfo Call" onclick="showInfo()" /> </body> </html>
Clicking on the first button makes a call to the showInfo method of the newly created object:
<input type="button" value="Good showInfo Call" onclick="myNewObject.showInfo()" />
As you would hope, the value of the info property is passed to the alert() dialog
The second button attempts to make a call directly to the function myFunc():
<input type="button" value="myFunc Call" onclick="myFunc()" />
Because myFunc() is a method of the global object (having been defined without reference to any other object as parent), it attempts to pass to the alert() dialog the value of a nonexistent property window.info
Finally, your third button attempts to call showInfo without reference to its parent
<input type="button" value="Bad showInfo Call" onclick="showInfo()" />
Because the method does not exist outside the object myNewObject, JavaScript reports an error
Anonymous Functions
There is a more convenient and elegant way to assign a value to your object’s showInfo method, without having to create a separate, named function and then later assign it by name to the required method. Instead of this code:
function myFunc() { alert(this.info); }; myNewObject.showInfo = myFunc;
You could simply have written the following:
myNewObject.showInfo = function() { alert(this.info); }
Because you haven’t needed to give a name to your function prior to assigning it, this technique is referred to as using an anonymous function.
Using a Constructor Function
Directly creating an instance of an object is fine if you think you’ll only need one object of that type. Unfortunately, if you need to create another instance of the same type of object, you’ll have to go through the same process again—creating the object, adding properties, defining methods, and so on
A better way to create objects that will have multiple instances is by using an object constructor function. An object constructor function creates a kind of “template” from which further objects can be instantiated.
Take a look at the following code. Instead of using new Object(), you first declare a function, myObjectType(), and in its definition you can add properties and methods using the this keyword.
function myObjectType(){ this.info = 'I am a shiny new object'; this.showInfo = function(){ alert(this.info); // show the value of the property info } this.setInfo = function (newInfo) { this.info = newInfo; // overwrite the value of the property info } }
In the preceding code you added a single property, info, and two methods: showInfo, which simply displays the value currently stored in the info property, and setInfo. The setInfo method takes an argument, newInfo, and uses its value to overwrite the value of the info property.
Instantiating an Object
You can now create as many instances as you want of this object type. All will have the properties and methods defined in the myObjectType() function. Creating an object instance is known as instantiating an object.
Having defined your constructor function, you can create an instance of your object simply by using the constructor function:
var myNewObject = new myObjectType();
Now you can call its methods and examine its properties:
var x = myNewObject.info // x now contains 'I am a shiny new object' myNewObject.showInfo(); // alerts 'I am a shiny new object' myNewObject.setInfo("Here is some new information"); // overwrites the info property
Creating multiple instances is as simple as calling the constructor function as many times as you need to:
var myNewObject1 = new myObjectType(); var myNewObject2 = new myObjectType();
Creating Objects with a Constructor Function
<!DOCTYPE html> <html> <head> <title>Object Oriented Programming</title> <script> function myObjectType(){ this.info = 'I am a shiny new object'; this.showInfo = function(){ alert(this.info); } this.setInfo = function (newInfo) { this.info = newInfo; } } var myNewObject1 = new myObjectType(); var myNewObject2 = new myObjectType(); </script> </head> <body> <input type="button" value="Show Info 1" onclick="myNewObject1.showInfo()" /> <input type="button" value="Show Info 2" onclick="myNewObject2.showInfo()" /> <input type="button" value="Change info of object2" onclick="myNewObject2.setInfo('New Information!')" /> </body> </html>
Using Constructor Function Arguments
There is nothing to stop you from customizing your objects at the time of instantiation, by passing one or more arguments to the constructor function. In the following code, the definition of the constructor function includes one argument, personName, which is assigned to the name property by the constructor function. As you instantiate two objects, you pass a name as an argument to the constructor function for each instance.
function Person(personName){ this.name = personName; this.info = 'I am called ' + this.name; this.showInfo = function(){ alert(this.info); } } var person1 = new Person('Adam'); var person2 = new Person('Eve');
You can define the constructor function to accept as many or as few arguments as you want:
function Car(Color, Year, Make, Miles) { this.color = Color; this.year = Year; this.make = Make; this.odometerReading = Miles; this.setOdometer = function(newMiles) { this.odometerReading = newMiles; } var car1 = new Car("blue", "1998", "Ford", 79500); var car2 = new Car("yellow", "2004", "Nissan", 56350); car1.setOdometer(82450);