Section J. Objects


J. Objects

Objects are useful storage units for variables and functions that are related to each other. For instance, in JavaScript every HTML element is represented by an object, which conveniently gathers all relevant information about the element in one place, where it is easy to access and change.

Take this form field:

<input name="name" value="ppk"  /> 


You can access it by doing this:

var formField = document.getElementById('myname'); 


In most other chapters, I'll say that "formField now contains the form field". In this section, though, we're going to be very finicky and precise, so instead I say that the variable formField now holds a reference to the JavaScript object that represents the HTML form field.

An object is nothing more than a collection of properties. Properties whose values are functions (such as event handlers) are called methods. In JavaScript there is no difference between variables and properties, and between functions and methods. Nonetheless, it's customary to speak of the methods and properties of an object.

Properties have a name and a value, and calling a property by name reveals its value. Let's read out a few properties of our object:

var formField = document.getElementById('myname'); alert('The form field with name ' + formField.name + ' has value ' + formField.value); 


The name and value properties of the form-field object coincide with the HTML name and value attributes. Reading out these properties reveals their values, which are shown in the alert. The alert faithfully reads "The form field with name name has value ppk".

We can also change these properties:

formField.name = 'author'; alert('The form field with name ' + formField.name + ' has value ' + formField.value); 


Now the alert reads "The form field with name author has value ppk", and if the form is submitted to the server, the form field's name will be author.

We can also define methods on it:

formField.onclick = function () {     alert('The form field with name ' + formField.name + ' has value ' + formField.value); } 


Now the alert is shown whenever the user clicks on the form field.

Thus the formField object represents the HTML form field, and there's an object for every single HTML element in a page. Since these objects all contain useful information about the HTML elements they represent, and even allow you to modify the elements, you'll use these objects continuously in your scripts.

The dot

As you see in the code examples, every time I want to access a method or property of the object formField, I start with formField. and then add the name of the method or property. That immediately defines the purpose of the dot operator: it is used to access methods or properties of an object. The object itself is named on the left side of the dot, the method or property on the right side.

Therefore, any time you see a dot anywhere in JavaScript code, you know that an object is being asked for a method or property. This can be a simple operation, like formField.name ("access the name property of object formField"), or it can be something more complicated, like this:

var x = document.getElementById('test').getElementsByTagName('a'); 


This statement uses two dots, and therefore you immediately know that at least two objects are being accessed (in fact, there are several more involved). First we access the getElementById method of the document object (document.getElementById) and execute it (('test')).

This method returns yet another object (let's be precise: it's a reference to the object that represents the element with id="test"), and we access the getElementsByTagName method of this new object in order to get all <a> tags contained by this HTML element. The result is a nodeList object.

Although this may sound pretty complicated, you'll intuitively do the right thing whenever you use this sort of statement, and you rarely have to worry about the exact meaning. You now have access to all links in the element with id="test", and that's what counts.

Defining objects

Until now we worked with predefined objects. These come in two flavors: internal JavaScript objects (such as the String objects discussed in 5F), and host objects, or objects created by JavaScript's host (the browser). Host objects include those that represent each HTML element in your pages. The remaining chapters will focus almost exclusively on this herd of host objects.

There's a third flavor of object: those you define yourself. Although this book doesn't treat object-oriented programming, you should know how to create your own objects.

The following is perfectly legal (though a bit ponderous) JavaScript that creates an object:

var test = new Object(); test.a = 2; test.b = '2'; test.c = function () {     alert(test.a * test.b); } 


We first officially state that test becomes a new object. Then we define a, b, and c as properties of the object, and give them values. Since c's value is a function, c becomes a method.

When we execute the method, an alert containing the number 4 pops up, just as if we'd used normal variables and functions:

test.c(); 


Object literals

JavaScript also allows you to use an object literal instead of how we did it in the previous code:

var test = {     a: 2,     b: '2',     c: function () {            alert(test.a * test.b);     } } 


Executing test.c() alerts 4, just as in the previous example. Note that the syntax of an object literal is precise:

{     propertyName: propertyValue,     methodName: function () {             // function body     },     propertyName: propertyValue // note: no comma } 


The entire object literal is enclosed in curly braces, and inside those braces all methods and properties are defined. First comes the property name, then a colon, then the property value (which of course may be a function), followed by a comma. However, this comma is forbidden after the very last property value.

We'll encounter a practical example of object literals in 10C.

Working with methods and properties

Whether you use internal JavaScript objects, host objects, or self-defined objects, they all contain methods and properties.

Many properties of host objects have predefined behavior. Take the href property of the location object that holds the URL of the current page. When you change the value of this property, the browsers interpret it as a command to load a new page (see 6C).

Predefined properties generally work as described: "If you set this property to that value, this will happen." Sometimes, though, the property works only in one browser.

You can create any property you want, just as you can create any variable you want. Even when some browsers interpret a change in a property's value as a command to do something while other browsers don't, setting the property doesn't hurt.

You can also access any property you want, even if it does not exist. In 5G we tried to access the target property of the event object, and saw that in Explorer its value is undefined, since Explorer uses the srcElement property instead. Nonetheless, accessing target is safe, as long as you don't mind the value undefined creeping up in your scripts.

Methods are another story, though. When you execute a method, you in fact do two things: first you access it, and then you try to execute it. Accessing the method is always safe, just as with properties, but executing it is not.

Example

An example will clarify these rules. As we'll see in 7D, sometimes it's useful to stop the propagation of an event (just nod wisely for the moment). The problem is that this functionality exists in two flavors: W3C-compliant browsers use the stopPropagation()method of the event object, while Microsoft uses a property of the event object: cancelBubble.

This is the correct way to handle the situation:

function stopProp(e) { // e is the event object     if (e.stopPropagation)            e.stopPropagation();     e.cancelBubble = true; } 


e holds the event object. We first want to execute the stopPropagation() method, but we can't just go off and do it. In Explorer this method doesn't existand that really means that if you access the stopPropagation property of the event object, you get undefined. Executing this value as a method is obviously impossible and gives an error message.

Therefore we start out by checking if the event object has a method stopPropagation (if (e.stopPropagation)). If it does, we execute e.stopPropagation().

Then we set Explorer's cancelBubble property to true. Since we don't use any kind of object detection, all browsers, including the W3C-compatible ones, execute this line of code. This does not lead to error messages. You can always define any property you like, so this action is legal. W3C-compliant browsers shrug and create a property cancelBubble with value true. Of course they don't do anything with this new value, because they're not programmed to do so. Only Explorer interprets this assignment as a command to stop the propagation of the event.

Creating your own properties

Creating your own properties is sometimes useful. Of course these properties don't have any predefined meaning in the browsers, so you have to write scripts that do something with the values they contain.

Let's take a look at an example from Sandwich Picker:

[Sandwich Picker, lines 193-202]

function calculateTotalPrice() {     var price = 0;     var containers = [all trs in the ordered table]     for (var i=1;i<containers.length;i++) {             var searchFields = [the input];             var amount = searchFields[0].value;             price += containers[i].price * amount;     }     document.getElementById('priceDisplay').innerHTML = createReadablePrice(price); } 


Note that containers[i].price is a property of the object containers[i]. Why do I use a property to store the price? While Sandwich Picker runs, <tr>s containing sandwiches will constantly be transferred from one table to another as the user searches, orders, and trashes them. Therefore I make sure that every object that represents a <tr> holds a variable with the price of the sandwich, so that I always have easy access to this price, regardless of the exact location of the <tr> in the page.

The this keyword

The this keyword is very powerful, provided you know how to use it. this can be used in any function or method, and it always refers to the object the method is defined on. Take a look at the simple test object we studied a while back:

var test = new Object(); test.a = 2; test.b = '2'; test.c = function () {     alert(this.a * this.b); // was alert(test.a * test.b); } 


I replaced test.a and test.b with this.a and this.b. The method still works. When it encounters the this.a, it takes the object it is defined on (test) and goes to the a property.

We use the this keyword all the time in event handling. To understand why, let's look at an even older example:

formField.onclick = function () {     alert('The form field with name ' + formField.name + ' has value ' + formField.value); } 


Here we define an onclick event handler on a form field. It fires whenever the user clicks on the form field. With our newly acquired object knowledge we can easily see two important things:

  1. The onclick event handler is in fact a method of the formField object.

  2. The this keyword will refer to this formField object when used inside the event handler.

Therefore we can also do the following:

formField.onclick = function () {     alert('The form field with name ' + this.name + ' has value ' + this.value); } 


We'll discuss this important technique further in 7F.

The global object

If properties are really variables, it stands to reason that variables, even global ones, are really properties. But properties of which object?

The answer is: they are properties of the global object. JavaScript automatically creates a global object to hold all the variables, functions, and objects you define.

JavaScript Core does not state which object becomes the global object; specific implementations are left to make that decision. Client-side JavaScript uses the window object:

var exampleString = 'I am a JavaScript hacker'; alert(window.exampleString); 


The variable exampleString is the exampleString property of the window object, and the alert works.

In itself this is not really useful. You'll rarely encounter situations in which saying window.exampleString is better than just saying exampleString. Nonetheless, it's correct JavaScript.



ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ppk on JavaScript. Modern, Accessible, Unobtrusive JavaScript Explained by Means of Eight Real-World Example Scripts2006
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net