Rodrigo Fonseca
Rodrigo Fonseca

Reputation: 944

Javascript, Prototype and Inherit

I've this code:

var Parent = function(){};
var Child = function(){};

function inherit(C, P){
    C.prototype = new P();//received a pointer to Parent
    C.prototype.test = function(){};
}

inherit(Child, Parent);
console.log(new Parent);//Object {}
console.log(new Child);//Object {test=function()}

Now i've a question, if C.prototype received a pointer to Parent in my inherit function, why my "console.log(new Parent)" doesn't show like this: "Object {test=function()}" to Parent and "Object {}" to Child?

Upvotes: 2

Views: 139

Answers (3)

HMR
HMR

Reputation: 39270

To understand this better you have to know the difference between mutating an object and re assigning it.

a=22;//assigns value to a
a.something=22;//mutates it
a.push(22);//if a is an array then push will mutate it

As explained in my link in the comments: you can't re assign prototype members through instances (Child.prototype is an instance of Parent) but you can mutate them (I advice reading the link posted). Here is some sample code:

var Test = function(){};
Test.prototype.something={a:1};
Test.prototype.somethingElse={a:2};
var t = new Test();
//mutating someting in t will change 
//  Test.prototype.someting
t.something.a=3;
//re assigning somethingElse will not
// change Test.prototype.somethingElse
// instead it will create a member called
// somethingElse on t 
t.somethingElse=3;
var anotherT =  new Test();
console.log(anotherT.something);//{a=3}
console.log(anotherT.somethingElse);//{a=2}
console.log(t.somethingElse);//3
console.log(t.hasOwnProperty("somethingElse"));//true
//next is false because anotherT.sometingElse comes
// from the prototype chain and not directly from antohrT
console.log(anotherT.hasOwnProperty("somethingElse"));//false

When passing variables to functions this works the same way:

var assignVal=function(obj){
  obj=22;
};
var mutateVal=function(obj){
  obj.mutated=22;
};

var o = {msg:"Hello World"};
assignVal(o);
console.log(o);//{msg="Hello world"}
mutateVal(o);
console.log(o);//{msg="Hello world",mutated=22}

Upvotes: 0

Philipp Gayret
Philipp Gayret

Reputation: 5070

Taken out the function to simplify;

var Parent = function(){};
var Child = function(){};

Child.prototype = new Parent();//"received a pointer to Parent"
Child.prototype.test = function(){};

console.log(new Parent);//Object {}
console.log(new Child);//Object {test=function()}

Child.prototype is now a reference to an instance of a Parent, to illustrate, what you did could also be written as:

var Parent = function(){};
var Child = function(){};

var instance = new Parent();
instance.test = function(){};
Child.prototype = instance;

console.log(new Parent);//Object {}
console.log(new Child);//Object {test=function()}

Putting properties on the instance does not affect the Parent prototype, which is why the console log doesn't show the test function on the Parent prototype. It would be the same as doing ( almost the same ):

var instance = {
    test: function(){}
};
instance.prototype = Parent;

Upvotes: 3

Theofilos Mouratidis
Theofilos Mouratidis

Reputation: 1156

The new P(), creates a new space in ram and stores a P instance.
Don't forget you change C.(new P).test, not C.P.test, there is difference. new P and P have different pointers, same as new P with new P. Check what does the new keyword in OOP like Java and then you will clear it out.

Upvotes: 1

Related Questions