Search code examples
javascriptinheritanceobjectprototype-programming

Prototypes and object creation


Lately I'm trying to get the technical aspects of the prototype chain. Now I have a few questions about object instantiation.

Consider the following code:

var Foo = function(s) {
  this._bar = s;
};

var fooInst = new Foo('test');

Now when I examine the created object, then:

Foo.prototype === Function.prototype; // true

fooInst.prototype === ?
fooInst.prototype.prototype === Object.prototype; // true

I'm wondering, what fooInst.prototype exactly is. In Chromes inspector it seems to be some kind of Foo with an constructor property. But all sources I read about prototypes state that fooInst.prototype === Foo.prototype should be true.

So my question: how exactly does JS handle the prototype chain. What exactly happens when I call new Foo.

Thanks in advance!

Edit

So I found, that (in Chrome) Object.getPrototypeOf(fooInst) === Foo.prototype; is true, but Object.getPrototypeOf(fooInst) === Object.getPrototypeOf(Foo) is false. Why that?


Solution

  • I'm wondering, what fooInst.prototype exactly is.

    It is undefined.

    fooInst.prototype === undefined; // true
    

    Only functions have an automatic .prototype property. Objects do not.

    If you create an object using a constructor, like:

    var fooInst = new Foo('test');
    

    ...then fooInst will have an internal reference to Foo.prototype, but there's no standard property to get Foo.prototype from fooInst.


    That said, there is a non-standard property that is supported in some JavaScript environments for referencing the prototype object.

    fooInst.__proto__ === Foo.prototype; // true (if __proto__ supported)
    

    Also, there is a method provided by ECMAScript 5 that can be used.

    Object.getPrototypeOf( fooInst ) === Foo.prototype;  // true
    

    That internal reference from an object to its prototype object can be just the first in a chain of such references.

    The prototype object likely has its own prototype object that is referenced. (In basic cases, this will be Object.prototype, or with longer chains, Object.prototype may be further down the chain.)

    Object.prototype itself references null as its prototype. This ends the chain.

    You should note that the internal reference from an object to its prototype object does not change if you change the .prototype object of the constructor function. It is a reference that exists for the life of the object.

    var Foo = function(s) {
      this._bar = s;
    };
    
    var fooInst = new Foo('test');
    
    Object.getPrototypeOf( fooInst ) === Foo.prototype;  // true
    
    // Change the prototype object of Foo
    Foo.prototype = { some:'object' };
    
    Object.getPrototypeOf( fooInst ) === Foo.prototype;  // false