All objects automatically inherit their prototype from their constructor, so even if you set it from within, it will revert back to the constructor afterwards.
You will need to set the prototype from outside of the constructor.
The way the prototype chain is established is by a secret property on the object, named proto. You can’t play with it except for in firefox. I think it only makes sense that isPrototypeOf() reads that hidden property. That’s why this works in firefox.
var monkey = {
hair : true,
feeds : 'bananas',
breathes: 'air'
};
function Human(name){
this.name = name;
this.__proto__ = monkey;
};
var david = new Human('David');
monkey.isPrototypeOf(david);
I’m not sure if I’m right, but this post sums my understanding of it.
I’m still getting to grips with it myself, but the proto link is key. As crmalibu has mentioned
It’s worth experimenting with the proto to figure out what’s going on.
When you make a new instance like david from your Human constructor you end up with a new object with it’s own name property and a secret proto property which points to the Human constructor’s prototype.
A bit of experimenting
function Human(name){
this.name = name;
};
// Note set outside of the constructor
Human.prototype.getName = function(){return this.name};
var david = new Human('David');
console.log(Human.prototype.isPrototypeOf(david)); // true
// david doesn't have a prototype object.
console.log(david.prototype); // Undefined. no prototype
// david does have a __proto__ link though
// david's __proto__ link points to the Human constructor's prototype object
console.log(david.__proto__); // Object {getName = function(){....}}
// which inturn has a link to the constructor through the constructor property
console.log(david.__proto__.constructor); // Human(name){.....}
// the Human's prototype in turn has a __proto__ pointing back to Object.prototype
console.log(david.__proto__.__proto__); // Object {}
// Let's introduce monkey to the mix
var monkey = {
hair : true,
feeds : 'bananas',
breathes: 'air'
};
// change the Human prototype to monkey
Human.prototype = monkey;
console.log(david.prototype); // still undefined
console.log(david.__proto__); // Surprise. Still points to the old prototype Object {getName......
var paul = new Human('Paul');
console.log(paul.prototype); // still undefined
// paul's __proto__ link points to monkey
console.log(paul.__proto__); //Object {hair: true, feeds: 'bananas', breathes: 'air'}
This is a tad confusing to me, because it insinuates that david has it own constructor property. As far as I can see when you use david.constructor it requires a lookup via the proto chain to find a constructor property. Well atleast that’s how it appears to me.
I.e.
function Human(name){
this.name = name;
};
Human.prototype.getName = function(){return this.name};
var david = new Human('David');
// looks up the constructor property
console.log(david.constructor); //Human(name)
// finds it via it's __proto__ link
console.log(david.__proto__.constructor); //Human(name)
// this is where it is
console.log(Human.prototype.constructor); //Human(name)
function AnotherConstructor(){};
//change the Human.prototype.constructor to another object
Human.prototype.constructor = AnotherConstructor;
console.log (david.constructor); // AnotherConstructor()
monkey.prototype // undefined
monkey.constructor // function Object()
monkey.constructor.prototype // Object, or {}
monkey.proto // function Empty()
monkey.proto.constructor // function Object()
monkey.proto.constructor.prototype // Object or {}