0

Here i have two constructor say First and Second.

First inherits from Second.First also has a hair property on its prototype chain.

A newly created object say tom which supposed to be an instance of First constructor has also a user-defined property called nail.

If i want to log all the enumerable properties of tom object using a for...in loop it only shows name,nail and age.But hair property seems to be disappeared from its prototype chain.

Why hair property disappeared from the prototype chain?? How can i get it back??

<html>
<body>
<script>
   function First(name){
       this.name=name;
   }
   First.prototype.hair='black';// tom.hair gets me undefined
   function Second(){
       this.age=1;
   }

   First.prototype=new Second();
   var tom=new First('tom');
   tom.nail='sharp';// added property to tom
   for(var i in tom){
       console.log(i);
   }
   console.log(tom.hair);
</script>
</body>
</html>
AL-zami
  • 8,902
  • 15
  • 71
  • 130
  • You may want to re use Second constructor by calling Second.call(this) and use Object.create instead of creating an instance of Second to be used as First.prototype as now you're mixing up shared and instance specific members (age) more info here: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Sep 14 '14 at 10:23

3 Answers3

2

You overrode the prototype on

First.prototype=new Second();

make it

First.prototype.age=new Second().age;

and it works.

JSFIDDLE.

loveNoHate
  • 1,549
  • 13
  • 21
  • this statement is not clear First.prototype.age=new Second();can you elaborate your answer.i mean why it works?? – AL-zami Sep 14 '14 at 09:31
  • When you start the line `First.prototype=new Second();` you override the whole `prototype` object. Also `.prototype.hair`. The `.hair` does not exist anymore, since you are saying something like `prototype={}`. – loveNoHate Sep 14 '14 at 09:33
  • the first part is correct, but the solution is incorrect - the `age` property is now an object instead of `1` – CupawnTae Sep 14 '14 at 09:34
  • 1
    Your new log is showing you a `Second` object with an `age` property of `1`, where it should just be showing `1`. If you `console.log(tom.age.age)` you will get `1` when you should get `undefined`. Basically, instead of setting a new prototype, your solution adds a property to the existing one, which is not what the OP is trying to achieve – CupawnTae Sep 14 '14 at 09:42
  • @CupawnTae Got you, got you. ;) – loveNoHate Sep 14 '14 at 09:42
  • Your edit doesn't fix it though, because now you're only setting an `age` property on the existing prototype. The OP wants to set the prototype to an instance of `Second`, which you solution doesn't do – CupawnTae Sep 14 '14 at 09:44
  • @CupawnTae Ok, if `second` gets more properties than one, your solution of switching will only work! But I think, the whole question was about the **overriding** of the `object`, which I enclosed. – loveNoHate Sep 14 '14 at 09:48
  • 1
    interesting solution though.Learned some new logic :) – AL-zami Sep 14 '14 at 09:50
  • Yeah, if you really want to flip: You can add sth. to the `protoype` on click. AFTER initialisation. %)P – loveNoHate Sep 14 '14 at 09:52
1
First.prototype.hair 

is declared before

First.prototype 

is overwritten with an instance of an object constructed by Second when

First.prototype=new Second(); 

is called. To keep the hair property added to the prototype of First, add it to the prototype after you assign a instance of an object created by calling Second i.e.

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

function Second(){
    this.age=1;
}

First.prototype=new Second();

// add to prototype after overwriting/assigning prototype above
First.prototype.hair='black';

var tom=new First('tom');
tom.nail='sharp';

for(var i in tom){
    console.log(i);
}
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
1

The problem is you set the hair property on the default prototype for First and then replace it with a new prototype, which means your original is lost. If you reorder the statements like this it will work:

function First(name){
    this.name=name;
}
function Second(){
    this.age=1;
}

First.prototype=new Second();
First.prototype.hair='black'; // this works now!

var tom=new First('tom');
tom.nail='sharp';// added property to tom
for(var i in tom){
    console.log(i);
}
console.log(tom.hair);
CupawnTae
  • 14,192
  • 3
  • 29
  • 60