2

I've stumbled upon a very odd issue in my last project. I've implemented inheritance as follows:

 function Parent(){}
 Parent.prototype.hi = function(){
 alert("Parent: hi!");
 };
 Parent.prototype.bye = function(){
 alert("Parent: bye!");
 };
 function Child(){
 this.hi = function(){
 alert("Child: hi!");
 };
 }
 Child.prototype = new Parent();

This way I can override only the functions I need in the Child constructor, and the remaining will be inherited from the parent.

This works ok. Here's the test:

var test = function(){
 var p = new Parent();
 p.hi();
 p.bye();
 var c = new Child();
 c.hi();
 c.bye();
};
test();

And the output is the expected:

Parent: hi!
Parent: bye!
Child: hi!
Parent: bye!

However, when I store the instances in an array, the bye function in the children instance is not inherited, and it throws an error. Test code:

var anArray = [
 new Parent(),
 new Child()
];
var test2 = function(){
 for(var i = 0, m = null; i < anArray.length; i++){
 m = anArray[i];
 m.hi();
 m.bye(); //WTF not working for the child?
 }
};
test2();

Output:

Parent: hi!
Parent: bye!
Child: hi!
TypeError: m.bye is not a function

JSFiddle here

I've spent more than an hour staring at this code and debugging it, and I can't see where is the problem. The original code was way more complex and had more functions. I think something is wrong with the array, but I don't want to give up on it because I think a table-driven method is the best approach for what I'm trying to implement.

asked Jul 2, 2014 at 15:36
4
  • In your Child() function you are only defining this.hi, not this.bye. That's why bye() is coming back as undefined. Commented Jul 2, 2014 at 15:48
  • @athms: No, that's not the reason. Commented Jul 2, 2014 at 15:49
  • Assigning a value to a variable or property never changes the value of another variable or property. Hence assigning a new value to Child.prototpye cannot change the prototype of existing instances. Commented Jul 2, 2014 at 15:57
  • @FelixKling Yes, "existing" is the key word. I've not shown it, but the whole code was inside a module. I happen to forget a lot that a module is regular code executed, and tend to think of it as a bunch of function definitions. Commented Jul 2, 2014 at 16:01

1 Answer 1

2

The array with the new Child instance was created before you let Child inherit from Parent, and does still have the old prototype (without any methods). In contrast, the c = new Child is executed in the test() function after the Child.prototype = ... assignment.

Move the array declaration/initialisation into the test2 function. Or simply move all class stuff to the top.

answered Jul 2, 2014 at 15:48
Sign up to request clarification or add additional context in comments.

1 Comment

Oh man. I could have stared at that code a whole day. Of course hoisting works only for the function definition, but the inheritance is regular code and order matters. Me and my stupid Java mindset. Thanks a lot.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.