I'm not understanding why in the following code, obj.BaseMethod
doesn't return the method defined in BaseClass
constructor. In other words, why is it that
SubClass.prototype.BaseMethod
is defined, but
new SubClass().prototype.BaseMethod
is undefined.
I'm obviously missing something important here.
function BaseClass() {
var privatestuff = "blah";
return {
BaseMethod: function() {
console.log('BaseMethod called');
}
}
}
function SubClass() {
var moreprivates = "stuff";
return {
SubClassMethod: function() {
console.log('SubClassMethod called');
}
}
}
SubClass.prototype = new BaseClass();
var obj = new SubClass();
obj.SubClassMethod(); // SubClassMethod called
obj.BaseMethod(); // Uncaught TypeError: undefined is not a function
UPDATE
I actually understood how to get my code working using
this.method = function() { }
in my constructor function. I just didn't understand why the code above didn't do the same thing.
The answer is that if you return an object in a constructor function, you are no longer using "protoypal" inheritance.
The thing that makes this most clear to me was this answer https://stackoverflow.com/a/2118831/834770
Quoting Douglas Crockford in Chapter 5, Inheritance, of JavaScript: (...)
Douglas Crockford then explains how the new operator could be implemented as a JavaScript function. This function makes use of several other functions defined in the book, so I rewrote it in a (somewhat) simpler form below:
function createNew(constructor) {
// a function to explain the new operator:
// var object = createNew(constructor);
// is equivalent to
// var object = new constructor();
//
// param: constructor, a function
// return: a new instance of the "constructor" kind of objects
// step 1. create a new empty object instance
// linked to the prototype of provided constructor
var hiddenLink = function(){};
hiddenLink.prototype = constructor.prototype;
var instance = new hiddenLink(); // cheap trick here: using new to implement new
// step 2. apply the constructor the new instance and get the result
var result = constructor.apply(instance); // make this a reference to instance within constructor
// step 3. check the result, and choose whether to return it or the created instance
if (typeof result === 'object') {
return object;
} else {
return instance;
}
}
So, in short, if you return an object in this function, then the inheritance bit is effectively ignored.