Prototype inheritance

Hey all,

In this line:


function inherit(C, P) {
  var F = function () {};
  F.prototype = P.prototype;
  C.prototype = new F();
}

Someone said that:


The new inheriting function will actually separate the constructor of the parent from the child, because it's not pointing to the same object anymore, but now it's pointing to a prototype of a newly created function that has nothing to do with the parent. So, you actually create a local copy of the parent's constructor, and then create a new instance of the copy, which returns all constructor methods an properties. By changing the constructor of the child now, it will not affect the parent.

My question is I don’t understand how the child has nothing to do with the parent anymore when indeed we ASSIGN A REFERENCE of P prototype to F prototype. So F prototype must be pointing to P’s prototype. When we instantiate F, the above quote says it contains a copy, but not a reference? apply() creates COPIES but object assignment creates REFERENCES so when assigning prototype, isn’t a refeence, not a copy, created from P to F? And if it’s a reference, then that link from C to F to P should still exist. But obviously it doesn’t in the language so I am clearly missing something.

Thanks for any clarification.

I see it a bit like this

function inherit(C, P) {
  var F = function () {};
  F.prototype = P.prototype;
  C.prototype = new F();
  C.prototype.constructor = C;
}

function Parent(name){
  this.name = name;
}

Parent.prototype.sayName = function(){
  alert (this.name);
}

function Child(){};

inherit(Child, Parent);

// F = function(){}
// F.prototype = P.prototype;
// C.prototype = new F();
// C's prototype is now an empty object with a __proto__ link to P's prototype object
// C now longer has a constructor name in it's prototype pointing back to C's constructor

var newChild = new Child();

// An instance of Child
// It's __proto__ link points to Child's empty prototype object
// In Child's empty prototype object has a __proto__ link pointing back to Parent's prototype 

Basically the Child constructor’s prototype is overwritten, which severs ties with the Child constructor.

I could be wrong but the above seem to make sense to me.

RLM

Thanks for reply.

I’m looking at this from memory position angle. Because F’s prototype points to the same memory position as P’s prototype and because prototype is an object and objects get passed around by reference so they reference same memory position during assignment.

p proto (memory position 001)
F.prototype = P.prototype;
F proto (memory position 001)
C.prototype = new F();
C proto (memory position 001)
So if interpreter can’t find property in C’s proto, it looks up parent object F and checks if it has the proto property and if it doesn’t, then it searches P. Hence, C can inherit from P.

But when you change C, and if C points to memory position 001, how can P not be affected, if P itself points to memory position 001?

Someone said it’s like C.prototype.prototype = P.prototype;

I don’t see how the language interprets that prototype property has a property called prototype when it’s not outright declared. All C’s prototype does is point to an object, which has its own prototype.

I’ve been stuck on understanding this for a week. Someone please explain why my memory position argument fails (despite the fact that objects passed by reference). How can the child be modified without the object it’s pointing to not be modified? That’s all I am asking.

Confused.

JohnMerlino,

I am learning myself, so I’m probably not the best person to ask necessarily.

The first thing that stands out though is the way you’re talking about P C and F

p proto (memory position 001)

F proto (memory position 001)

C proto (memory position 001)

P C and F are functions. It just so happens they are invoked as constructors with the ‘new’ keywords. Their purpose is to act as a kind of template for making new objects or copies.

The link that is formed, is between the new object and the constructor’s prototype. If the ‘constructor’ property on that prototype hasn’t been overwritten then we can access the constructor function.

P C and F’s proto pointers actually point to the default Function Object’s prototype, so as far as I can tell don’t really figure much in our end usage.

From a few tests I’ve run it does appear to confirm this.


function Parent(name){
  this.name = name || 'Adam';
}

Parent.prototype.sayName = function(){ alert(this.name) };

var child = new Parent();
delete child.name; // delete the copied name property of child

console.log (child.prototype);// Output: undefined (no prototype)
console.log (child.__proto__);// Parent.prototype
// Output:
// constructor: function Parent(name){
// sayName: function (){ alert(this.name) }
// __proto__: Object
console.log (child.__proto__.constructor.name);// Output: Parent
var anotherChild = new child.__proto__.constructor();
console.log (anotherChild.name); // Adam


// Some more tests
// Note: Messing with Function and Object.prototype not recommended
// Just trying to get some sort of clarification
Function.prototype.test = function(){ alert ("Function.prototype")};
Object.prototype.test = function(){ alert ("Object.prototype")};

console.log(Parent.__proto__); // function Empty(){} (doesn't really tell us much)
console.log(Function.prototype); // function Empty(){}
Parent.__proto__.test(); // alerts 'Function.prototype'
Parent.__proto__.__proto__.test(); // alerts 'Object.prototype'

RLM

It was recommended on another forum that you check out the official ECMA documents. ECMA-262.pdf

If you look at section 4.2.1 you should find some relevant information.

‘implicit prototype link’ I believe refers to the proto link.

RLM