JAVA SCRIPT - Using Prototype to Create Objects

Using Prototype to Create Objects


PROBLEM


You want to create a new object, but you don’t want to add all the properties and methods into the constructor function. 

Solution

Use the object’s prototype to add the new properties:
Tune.prototype.addCategory = function(categoryName) {
 this.category = categoryName;
}
EXPLAIN Object is the ancestor for every object in JavaScript; objects inherit methods and prop‐ erties from the Object via the Object prototype. It’s through the prototype that we can add new methods to existing objects:


var str = 'one';
String.prototype.exclaim = function() {
 if (this.length == 0) return this;
 return this + '!';
}
var str2 = 'two';
console.log(str.exclaim()); // one!
console.log(str2.exclaim()); // two!


Before ECMAScript 5 added trim() to the String object, applications used to extend the String object by adding a trim method through the prototype object:

String.prototype.trim = function() {
 return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
}


Needless to say, you’d want to use extreme caution when using this functionality. Ap‐ plications that have extended the String object with a homegrown trim method may end up behaving differently than applications using the new standard trim method. To avoid this, libraries test to see if the method already exists before adding their own.

We can also use prototype to add properties to our own objects.the new object, Tune, is defined using function syntax. It has two private data members, a title and an artist. A publicly accessible method, concatTitleArtist(), takes these two private data members, concatenates them, and returns the result. After a new instance of the object is created, and the object is extended with a new method (addCategory()) and data member (category) the new method is used to update the existing object instance.
.

 Instantiating a new object, adding values, and extending the object



function Tune(title,artist) {
 this.concatTitleArtist = function() {
 return title + " " + artist;
 }
}
// create instance, print out values
var happySong = new Tune("Putting on the Ritz", "Ella Fitzgerald");
// extend the object
Tune.prototype.addCategory = function(categoryName) {
 this.category = categoryName;
}
// add category
happySong.addCategory("Swing");
// print song out to new paragraph
var song = "Title and artist: " + happySong.concatTitleArtist() +
 " Category: " + happySong.category;
console.log(song);



The result of running the code is the following line printed out to the console:
"Title and artist: Putting on the Ritz Ella Fitzgerald Category: Swing"
One major advantage to extending an object using prototype is increased efficiency.

 When you add a method directly to a function constructor, such as the concat TitleArtist() method in Tune, every single instance of the object then has a copy of this function. Unlike the data members, the function isn’t unique to each object instance.

When you extend the object using prototype, as the code did with addCategory(), the method is created on the object itself, and then shared equally between all instances of the objects. Of course, using prototype also has disadvantages. Consider again the concat TitleArtist() method. It’s dependent on access to data members that are not accessible outside the object.

If the concatTitleArtist() method was defined using prototype and then tried to access these data members, an error occurs. If you define the method using prototype directly in the constructor function, it is created in the scope of the function and does have access to the private data, but the data is overridden each time a new object instance is created:


function Tune(title,artist) {
 var title = title;
 var artist = artist;
 Tune.prototype.concatTitleArtist = function() {
 return title + " " + artist;
 }
}
var sad = new Tune('Sad Song', 'Sad Singer')
var happy = new Tune('Happy', 'Happy Singer');
console.log(sad.concatTitleArtist()); // Happy Happy Singer

The only data unique to the prototype function is what’s available via this. There are twisty ways around this, but they not only add to the complexity of the application, they tend to undermine whatever efficiency we get using prototype. Generally,

if your function must deal with private data, it should be defined within the function constructor, and without using prototype. Otherwise, the data should be available via this, or static and never changing once the object is created.

0 comments:

Post a Comment