To start our introduction to objects, let's think about what is meant by an object in the "real world" outside computing. The world is composed of things, or objects, such as tables, chairs, and cars (to name just a few!). Let's take a car as an example, so we can explore what an object really is.
How would we define our car? We might say it's a blue car with four-wheel drive. We might specify the speed at which it's traveling. When we do this, we are specifying properties of the object. For example, the car has a color property, which in this instance has the value blue.
How do we use our car? We turn the ignition key, press the gas pedal, beep the horn, change the gear (that is, choose between 1, 2, 3, 4, and reverse on a manual car, or drive and reverse on an automatic), and so on. When we do this, we are using methods of the object.
We can think of methods as being a bit like functions. Sometimes, we may need to use some information with the method, or pass it a parameter, to get it to work. For example, when we use the changing gear method, we need to say which gear we want to change to. Other methods may pass information back to the owner. For example, the dipstick method will tell the owner how much oil is left in the car.
Sometimes using one or more of the methods may change one or more of the object's properties. For example, using the accelerator method will probably change the car's speed property. Other properties can't be changed; for example, the body shape property of the car (unless you hit a brick wall with the speed property at 100 miles per hour!).
We could say that the car is defined by its collection of methods and properties. In object-based programming, the idea is to model real-world situations by objects, which are defined by their methods and properties.
In the previous chapters, we have (for the most part) been dealing with primitive data. This is actual data, such as strings and numbers. This type of data is not too complex and is fairly easy for us to deal with. However, not all information is as simple as primitive data. Let's look at an example to clarify things a little.
Suppose you had written a web application that displayed timetable information for buses or trains. Once the user has selected a journey, you might want to let him know how long that journey will take. To do that, you would need to subtract the arrival time from the departure time.
What would we need to do to calculate the difference between these two times? We would first need to separate out the hours from the minutes in each time. Then, to get the minutes difference between the two times, we would need to check whether the minutes of the arrival time were greater than the minutes of the departure. If so, we can simply subtract the departure time minutes from the arrival time minutes. If not, we need to add 60 to the arrival time minutes, and subtract one from the arrival time hours to compensate, before taking the departure time minutes from the arrival time minutes. We then need to subtract the departure time hours from the arrival time hours, before putting the minutes and hours that we have arrived at back together.
This would work OK, so long as the two times were in the same day. It wouldn't work, for example, with the times 23:45 and 04:32.
This way of working out the time difference obviously has its problems, but it also seems very complex. Is there an easier way to deal with more complex data such as times and dates?
This is where objects come in. We can define our departure and arrival times as Date objects. Because they are Date objects, they come with a variety of properties and methods that we can use when we need to manipulate or calculate with the times. For example, we can use the getTime() method to get the number of milliseconds between the time in the Date object and January 1, 1970, 00:00:00. Once we have these millisecond values for the arrival and departure times, we can simply subtract one from the other and store the result in another Date object. To retrieve the hours and minutes of this time, we simply use the getHours() and getMinutes() methods of the Date object. We'll see more examples of this later in the chapter.
Array objects have a property called length that tells us how many pieces of data, or rather how many elements, the array holds. We actually used this property in the Trivia Quiz in Chapter 3 to work out how many times we needed to loop through the array.
Array objects also have a number of methods. One example is the sort() method, which can be used to sort the elements within the array into alphabetical order.
In this section, we'll look at how we go about creating an object and, having done that, how we use its properties and methods.
So how is this statement made up?
The first half of the statement is familiar to us. We use the var keyword to define a variable called myArray. This variable is initialized, using the assignment operator (=), to the right-hand side of the statement.
We also saw in Chapter 2 that we can pass parameters to the constructor Array() to add data to our object. For example, to create an Array object that has three elements containing the data "Paul", "Paula", and "Pauline", we use
var myArray = new Array("Paul", "Paula", "Pauline");
Let's see some more examples, this time using the Date object. The simplest way of creating a Date object is
var myDate = new Date();
This will create a Date object containing the date and time that it was created. However,
var myDate = new Date("1 Jan 2000");
will create a Date object containing the date 1 January 2000.
var myNumber = 23;
var myArrayRef = new Array(0, 1, 2); var mySecondArrayRef = myArrayRef; myArrayRef = 100; alert(mySecondArrayRef);
First we set variable myArrayRef reference to the new array object, and then we set mySecondArrayRef to the same reference—for example, now mySecondArrayRef is set to reference the same array object. So when we set the first element of the array to 100 as shown here:
and display the contents of the first element of the array referenced in mySecondArrayRef as follows:
we'll see it also magically has changed to 100! However, as we now know, it's not magic; it's because both variables referenced the same array object because when it comes to objects, it's a reference to the object and not the object stored in a variable. When we did the assignment, it didn't make a copy of the array object, it simply copied the reference. Contrast that with the following:
var myVariable = "ABC"; var mySecondVariable = myVariable; myVariable = "DEF"; alert(mySecondVariable);
In this case we're dealing with a string, which is primitive data type, as are numbers. This time it's the actual data that's stored in the variable, so when we do this:
var mySecondVariable = myVariable;
mySecondVariable gets its own separate copy of the data in myVariable. So the alert at the end will still show mySecondVariable as holding "ABC."
var myVariable = new ObjectName(optional parameters);
Accessing the values contained in an object's properties is very simple. We write the name of the variable containing (or referencing) our object, followed by a dot, and then the name of the object's property.
For example, if we defined an Array object contained in the variable myArray, we could access its length property using
This would give us the number of elements contained in the array.
But what can we do with this property now that we have it? We can use this property as we would any other piece of data and store it in a variable
var myVariable = myArray.length;
or show it to the user
In some cases, we can even change the value of the property, such as
However, unlike variables, some properties are read-only—we can get information from them, but we can't change information inside them.
Methods are very much like functions in that they can be used to perform useful tasks, such as getting the hours from a particular date or generating a random number for us. Again like functions, some methods return a value, such as the Date object's getHours() method, while others perform a task, but return no data, such as the Array object's sort() method.
Using the methods of an object is very similar to using properties in that you put the object's variable name first, then a dot, and then the name of the method. For example, to sort the elements of an Array in the variable myArray, you may use the following code:
Just like functions, you can pass parameters to some methods, where the parameters are placed between the parentheses following the method's name. However, whether or not a method takes parameters, we must still put parentheses after the method's name, just as we did with functions. As a general rule, anywhere you can use a function, you can use a method of an object.
You should now have a good idea about the difference between primitive data, such as numbers and strings, and object data, such as Dates and Arrays. However, I mentioned earlier that there is also a String object. Where does this fit in?
In fact there are String, Number, and Boolean objects corresponding to the three string, number, and Boolean primitive data types. For example, to create a String object containing the text "I'm a String object," we can use
var myString = new String("I'm a String object");
The String object has the length property just as the Array object does. This returns the number of characters in the String object. For example
var lengthOfString = myString.length;
would store the data 19 in the variable lengthOfString (remember that spaces are referred to as characters too).
But what if we had declared a primitive string called mySecondString holding the text "I'm a _primitive string" like this:
var mySecondString = "I'm a primitive string";
theResult = "23" + 23;
So, for our primitive string mySecondString, we can use the length property of the String object to find out the number of characters it contains. For example
var lengthOfSecondString = mySecondString.length;
would store the data 22 in the variable lengthOfSecondString.
The same ideas we have expressed here are also true for number and Boolean primitives and their corresponding Number and Boolean objects. However, these objects are not used very often, so we will not be discussing them further in this book.