AJAX In Action [288]
this.name=name;
this.size=size;
}
MyObject.prototype.tellSize=function(){
alert("size of "+this.name+" is "+this.size);
}
var myObj=new MyObject("tiddles","7.5 meters"); myObj.tellSize();
First, we declare the constructor as before, and then we add functions to the prototype. When we create an instance of the object, the function is attached. The keyword this resolves to the object instance at runtime, and all is well. Licensed to jonathan zheng Objects in JavaScript 599 Note the ordering of events here. We can refer to the prototype only after the constructor function is declared, and objects will inherit from the prototype only what has already been added to it before the constructor is invoked. The prototype can be altered between invocations to the constructor, and we can attach anything to the prototype, not just a function: MyObject.prototype.color="red"; var obj1=new MyObject(); MyObject.prototype.color="blue"; MyObject.prototype.soundEffect="boOOOoing!!"; var obj2=new MyObject(); obj1 will be red, with no sound effect, and obj2 will be blue with an annoyingly cheerful sound effect! There is generally little value in altering prototypes on the fly in this way. It’s useful to know that such things can happen, but using the prototype to define class-like behavior for JavaScript objects is the safe and sure route. Interestingly, the prototype of certain built-in classes (that is, those implemented by the browser and exposed through JavaScript, also known as host objects) can be extended, too. Let’s have a look at how that works now. B.2.3 Extending built-in classes JavaScript is designed to be embedded in programs that can expose their own native objects, typically written in C++ or Java, to the scripting environment. These objects are usually described as built-in or host objects, and they differ in some regards to the user-defined objects that we have discussed so far. Nonetheless, the prototype mechanism can work with built-in classes, too. Within the web browser, DOM nodes cannot be extended in the Internet Explorer browser, but other core classes work across all major browsers. Let’s take the Array class as an example and define a few useful helper functions: Array.prototype.indexOf=function(obj){ var result=-1; for (var i=0;i result=i; break; } } return result; } Licensed to jonathan zheng 600 APPENDIX B JavaScript for object-oriented programmers This provides an extra function to the Array object that returns the numerical index of an object in a given array, or -1 if the array doesn’t contain the object. We can build on this further, writing a convenience method to check whether an array contains an object: Array.prototype.contains=function(obj){ return (this.indexOf(obj)>=0); } and then add another function for appending new members after optionally checking for duplicates: Array.prototype.append=function(obj,nodup){ if (!(nodup && this.contains(obj))){ this[this.length]=obj; } } Any Array objects created after the declaration of these functions, whether by the new operator or as part of a JSON expression, will be able to use these functions: var numbers=[1,2,3,4,5]; var got8=numbers.contains(8); numbers.append("cheese",true); As with the prototypes of user-defined objects, these can be manipulated in the midst of object creation, but I generally recommend that the prototype be modified once only at the outset of a program, to avoid unnecessary confusion, particularly if you’re working with a team of programmers. Prototypes can offer us a lot, then, when developing client-side object models for our Ajax applications. A meticulous object modeler used to C++, Java, or C# may not only want to define various object types but to implement inheritance between types. JavaScript doesn’t offer this out of the box, but the prototype can come in useful here, too. Let’s find out how. B.2.4 Inheritance of prototypes Object orientation provides not only support for distinct object classes but also