Inheritance and Copy-on-Write in Javascript

Javascript uses prototypes for inheritance, so what happens when you change something that’s defined in the prototype? Given the class

var Test = function(name){
	this.name = name;
};

Test.prototype = 
{
	v : 12,
	setV : function(v) { this.v = v; },

	toString : function() {
		return this.name + ".v = " + this.v;
	}
};

Does the setV() method set the copy on the prototype or the instance?

To test this I created the following

// Very simple function to print a line to the page.
println = function(x){
	document.write(x);
	document.write("<BR>");
};

var a = new Test("a");
var b = new Test("b");
println(a.toString() + ", " + b.toString());

As expected this resulted in

a.v = 12, b.v = 12

So call setV()

println("Call a.setV(1);")
a.setV(1);
println(a.toString() + ", " + b.toString());

The result, a.v = 1, b.v = 12. This made sense when we think about how Javascript assigns the “this” operator when calling methods. The “this” operator will be the instance “a”, so “this.v = 1” will create a value on “a”, effectively performing a “copy on write” operation. This is nice. I can create behaviour in prototypes and reuse it.

So how do I modify the instance on the prototype? For example how do I create a shared member? One technique I have seen and used is to create properties on the constructor function itself. The Eclipse development environment will recognise this and denote them as “static members”.

Test.v = 12;

These are always accessed as properties of Test, so it works.

I tried

a.__proto__.setV(2)

The result, “a.v = 1, b.v = 2”, because A has its own copy of V so is not effected, but V still uses the value on the prototype.

Similarly

a.setV.call(a.__proto__, 3);

This resulted in “a.v = 1, b.v = 3”.

There may not be many situations to use this technique. Working at such a low level can be very powerful. It is useful to learn how the language works.

This entry was posted in javascript. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.