SlightlyLoony
Tera Contributor

find_real_file.pngIn our earlier examples (see links below the fold) we had two examples of instance properties: birth_date and call_name. To review, these are properties that exist in each instance of a class. For example, if I have two Dog instances (one for Miki and one for Lea), each of them will have its own birth_date and call_name, with independent values (that could be either the same or different from each other).

But what if you want a property that's the same for all instances of a class? Is there a way to do that?

You betcha!


You've actually already seen two examples of such properties: the methods we added to the Dog class (age and birthday). We added these two methods to the prototype of the Dog class, and by some special behind-the-scenes magic, JavaScript made them appear (without actually copying them) in every instance of the Dog class. Through the same mechanism, we can add other kinds of properties. For example, here we've added the taxon as a prototype property:

function Dog(name, born) {
this.call_name = name;
this.birth_date = born;
}

Dog.prototype = {
taxon: 'Canis lupus familiaris',

age: function() {
var dog_age_ms = new Date().getTime() - this.birth_date.getTime();
var dog_age_days = dog_age_ms / (1000 * 60 * 60 * 24);
var dog_age_years = Math.floor(dog_age_days / 365.25);
return dog_age_years;
},

birthday: function() {
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December'];
var month = this.birth_date.getMonth();
var day = this.birth_date.getDate();
return months[month] + ' ' + day;
}
}

Now if I run this test code:

var dog1 = new Dog('Miki', new Date(2006,1,11));
var dog2 = new Dog('Lea', new Date(1997,9,16));
gs.log(dog1.taxon);
gs.log(dog2.taxon);

I'll see this:

Canis lupus familiaris
Canis lupus familiaris

By setting the taxon property in the prototype, I've made it available to every instance of the Dog class.

What do you suppose happens if I do this?

var dog1 = new Dog('Miki', new Date(2006,1,11));
var dog2 = new Dog('Lea', new Date(1997,9,16));
gs.log(dog1.taxon);
gs.log(dog2.taxon);
dog2.taxon = 'Canis cutus';
gs.log('\nModified...');
gs.log(dog1.taxon);
gs.log(dog2.taxon);

I get this result:

Canis lupus familiaris
Canis lupus familiaris

Modified...
Canis lupus familiaris
Canis cutus

Is that what you expected? The dog2 instance has the modified property, but the dog1 instance does not. What you're seeing here is an example of one property overriding another. The code dog2.taxon = 'Canis cutus'; created an instance property for dog2 named taxon — the same name as the prototype property we'd already defined. Here's your first rule of overriding: instance properties always override prototype properties. If you define both, the instance property wins.

But suppose you had added this line instead: dog2.prototype.taxon = 'Canis cutus';? That would get an error when you run it, as prototype is a property of the Dog class, not of an instance of it. However, this would work: Dog.prototype.taxon = 'Canis cutus';. If you run the test code with that change, you'll see that both the dog1 and the dog2 instance have the modified taxon property.

If you're wondering what today's image is, it's the Butterfly Nebula (NGC 6302).