2

I created these objects and their methods.

var Door = function(no = 10) {
    this.number = isNaN(no) ? 10 : no;
}

var Room = function(door) {
    this.door = door instanceof Door ? door : new Door();
    this.name = 'Room';
}

function MyRoom(){
    this.name = 'MyRoom';
}
MyRoom.prototype = new Room();

function HerRoom() {
    this.name = 'HerRoom';
}
HerRoom.prototype = new Room();

var $myDoor = new Door(10);
var $herDoor = new Door(5);

var $myRoom = new MyRoom($myDoor);
var $herRoom = new HerRoom($herDoor);

console.log($myDoor, $myRoom.door);
// $myDoor.number is 10
// $myRoom.door.number is 10

console.log($herDoor, $herRoom.door);
// $herDoor.number is 5
// $herRoom.door.number is 10

I am wondering what I did wrong that makes $myDoor == $myRoom.door, BUT, $herDoor != $herRoom.door. Can anyone please help me to notice where my mistake is?

Update:

Since, I create

var $herDoor = new Door(5);
var $herRoom = new HerRoom($herDoor);

I am expecting that $herRoom.door.number is equal to $herDoor.number. Since,

$herDoor instanceof Door // true;
Dicky Bullin
  • 259
  • 1
  • 2
  • 10
  • 1
    you doornumbers will always be 10 - look at the answer of @gurvinder372 – messerbill Mar 10 '16 at 13:07
  • 2
    You're never calling your super constructor, and neither `HerRoom` nor `MyRoom` take an argument. Instead you rely on the [wrongly initialised prototype](https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here) to have that property. – Bergi Mar 10 '16 at 13:14
  • It looks as if when creating a new instance of HerRoom/MyRoom, it doesn't do anything with the door that you pass into it. It always constructs a new instance of a door to use as its prototype which has the default value of 10. Try changing both values to be 20 for example and see if $myRoom.number = 10 – mbx-mbx Mar 10 '16 at 13:15
  • `$myDoor == $myRoom.door` - um, no. They might have the same number, but they're not the same object. – Bergi Mar 10 '16 at 13:16
  • @Bergi I am actually talking about why $herDoor.number is not the same as $herRoom.door.number. I am sorry for bad explanation – Dicky Bullin Mar 10 '16 at 13:17
  • 1
    @DickyBullin $myRoom.door.number will always be 10. Change your code to var $myDoor = new Door(20); and you will see that $myRoom.door.number will be 10. It always creates a new of Door as its door property (i.e. does nothing with the $myDoor that you pass into MyRoom.) – mbx-mbx Mar 10 '16 at 13:26
  • @DickyBullin As you are using es6 anyway I created this ES6 fiddle for you to see how your js will look in es6: http://www.es6fiddle.net/ilmc3gw0/ – mbx-mbx Mar 10 '16 at 13:53
  • @DickyBullin: I saw that, I was trying to tell you that `$herRoom.door` and `$herDoor` are different objects. Passing the one to the constructor of the other doesn't magically make it a property. – Bergi Mar 10 '16 at 14:24
  • @Bergi I am sorry I didnt quite get what you meant back then. I didn't expect I'd miss that much. Sorry again.. – Dicky Bullin Mar 10 '16 at 15:06

1 Answers1

2

I am wondering what I did wrong that makes $myDoor == $myRoom.door, BUT, $herDoor != $herRoom.door.

Simply because you gave var $herDoor = new Door(5); while initializing $herDoor which assigned 5 to number property.

Changing the value in constructor call will give you the output you want

var $herDoor = new Door(10);

Apologies for late edit, it seems that you are hoping that after assigning the prototype of Room to MyRoom, Room's constructor will be invoked. Also, since you are not passing door object to the MyRoom, it will never get this object.

You need to make following changes

function Door (no) {
    this.number = isNaN(no) ? 10 : no;
}

function Room (door) {
    this.door = door instanceof Door ? door : new Door();
    this.name = 'Room';
}

function MyRoom(door){
    this.name = 'MyRoom'; Room.call(this, door); //door object is passed and Room constructor is invoked with it
}
MyRoom.prototype = Object.create(Room.prototype);
function HerRoom(door) {
    this.name = 'HerRoom'; Room.call(this, door);//door object is passed and Room constructor is invoked with it
}
HerRoom.prototype = Object.create(Room.prototype);

var $myDoor = new Door(10);
var $herDoor = new Door(5);

var $myRoom = new MyRoom($myDoor);
var $herRoom = new HerRoom($herDoor);

console.log($myDoor, $myRoom.door);
console.log($herDoor, $herRoom.door);
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • 1
    function(no = 10) is es6 functionality (default values). He may be using a transpiler. – mbx-mbx Mar 10 '16 at 13:10
  • @Magrangs oh ok. If OP confirms it I will remove it from my post – gurvinder372 Mar 10 '16 at 13:11
  • @gurvinder372 I tried to change it but $herDoor.number is still not the same as $herRoom.door.number. – Dicky Bullin Mar 10 '16 at 13:15
  • 1
    @Magrangs No, I am not using transpiler. But I think my browser supports es6. – Dicky Bullin Mar 10 '16 at 13:15
  • @DickyBullin when I tried with `var $herDoor = new Door(10);` it gave me 10. What did you tried after updating the code? – gurvinder372 Mar 10 '16 at 13:19
  • @gurvinder372 I ran the same whole code that I wrapped in the question. – Dicky Bullin Mar 10 '16 at 13:23
  • @DickyBullin Is it? Can you verify the output you get from this fiddle https://jsfiddle.net/qabgjy7o/ ? – gurvinder372 Mar 10 '16 at 13:24
  • @gurvinder372 I updated your fiddle https://jsfiddle.net/qabgjy7o/1/. It should be `var $herDoor = new Door(5);` instead of `var $herDoor = new Door(10);`. What I am trying to achieve is `$herDoor.number == $herRoom.door.number`. – Dicky Bullin Mar 10 '16 at 13:26
  • @DickyBullin But that is the reason why you are getting the output you are getting? If you want your program to print 5, you should give 5 else you need to pass the input that you want it to print. – gurvinder372 Mar 10 '16 at 13:27
  • @gurvinder372 I did give 5 to $herDoor and I assign it to $herRoom = new HerRoom($herDoor). Please check my updated question. – Dicky Bullin Mar 10 '16 at 13:32
  • @DickyBullin got it now. That is because of this line `this.door = door instanceof Door ? door : new Door();` in your Room constructor. Since here you are not passing the number from door and door is not an instance of Door. – gurvinder372 Mar 10 '16 at 13:36
  • @gurvinder372 I agree with you. I keep thinking that's the line causing problem. But why is `door instanceof Door` returns false while `$herDoor instanceof Door` does return true :(.. I guess I'll just have to keep checking. – Dicky Bullin Mar 10 '16 at 13:37
  • 1
    @gurvinder372 The door parameter going into that function is always undefined so will always create a new door with a door number of 10. – mbx-mbx Mar 10 '16 at 13:37
  • @Magrangs THANK YOU. I finally found the cause. You and gurvinder are right. I followed this http://stackoverflow.com/a/4152967/6019647. And added `Room.call(this, arg)`, which fixes everything. Thank you so much for your guys help. – Dicky Bullin Mar 10 '16 at 13:48
  • @DickyBullin As you are using es6 anyway I created this ES6 fiddle for you to see how your js will look in es6: http://www.es6fiddle.net/ilmc3gw0/ – mbx-mbx Mar 10 '16 at 13:53
  • @DickyBullin I have updated my post, Please have a look. – gurvinder372 Mar 10 '16 at 13:56
  • Thank you so much guys. @Magrangs – Dicky Bullin Mar 10 '16 at 14:12
  • Notice that [`MyRoom.prototype = Room.prototype;` isn't exactly inheritance](https://stackoverflow.com/questions/11088365/why-wouldnt-i-use-child-prototype-parent-prototype-rather-than-child-prototype-new-parent) – Bergi Mar 10 '16 at 14:25