Search code examples
javascriptprototype-programming

Javascript and function prototype assignment


I've always assumed that the prototype of a function was shared among all the objects, in a sense by reference. So if you change the value of a property of the prototype, all objects that share that prototype have the values change for them as well. So for instance below it seems that instead of the property bar being shared between all objects, it is copied. Is this right? Are the properties of the prototype of the constructor simply copied to all the class objects as they are created, or are they shared by linkage?

function foo()
{
     this.bar = 1;
}
function derived() { }
derived.prototype = new foo()

object1 = new derived()
object2 = new derived()

object1.bar = 2;
//but notice if I had said here derived.prototype.bar = 3, object1.bar would still equal 2 but object2.bar would equal 3
alert(object2.bar) // this prints 1;

Solution

  • When you assign object1.bar = 2, you are creating an own property on object1, this property exist only in that object instance, and it has nothing to do with its prototype.

    This property on object1 will shadow the value of the one existing on derived.prototype, this means that when you lookup object1.bar, it will find a value directly existing on that object.

    On the other side, if you lookup object2.bar, this object doesn't have an own bar property, so the property lookup will search on the object this one inherits from (derived.prototype) and it will find the value 1.

    Your object structure looks something like this:

     object1
     --------
    | bar: 2 | -----------------
     --------                   |         derived.prototype
                                |        ----------
                                |------> | bar: 1  | --    foo.prototype
     object2 (no own properties)|        ----------   |   ------------------
     --------                   |                     -> | constructor: foo |
    |        | -----------------                          ------------------
     --------                                                    |
                                                                 v
                                                         ------------------
                                                        | Object.prototype |
                                                         ------------------
                                                                 |
                                                                 v
                                                                null
    

    Where the ---> lines denote the internal [[Prototype]] link that expresses inheritance.