Reputation: 44872
I've got an abstract object defined like so...
var abs = module.exports = function abs(val){
if(!(this instanceof abs)){
return new abs(val);
}
abs.prototype.getName = function getName(){
return val.name;
}
}
and a concrete class that I want to inherit from it defined like so...
var concrete = module.exports = function concrete(val){
var abs = require('./abs');
if(!(this instanceof concrete)){
return new concrete(val);
}
concrete.prototype = Object.create(abs.prototype);
}
and when I write...
var anObject { name : "John" };
var concreteObject = new concrete(anObject);
concrete.getName();
I get the following error..
TypeError: Object #<conrete> has no method 'getName'
What am I doing wrong?
Upvotes: 0
Views: 102
Reputation: 665574
There are two errors (left alone the missing =
) in what your wrote:
concrete.getName()
does not work because concrete
is your constructor function. It has no such method.concreteObject.getName()
does not work because its prototype has no such method. You did overwrite concrete.prototype
in the constructor, but then the instance was already built with the old one. Check how the new
operator works.Therefore you need to fix those class definitions as well. As we've seen, one cannot access constructor arguments from the shared prototype functions - it would not make any sense. And assigning the prototype methods in the constructor would make the val
of the latest abs
invocation available to all instances. Ugh.
Use the prototype:
function abs(val) {
if (!(this instanceof abs))
return new abs(val);
this.val = val;
}
abs.prototype.getName = function getName(){
return this.val.name;
};
module.exports = abs;
or use a privileged instance method (see Javascript: Do I need to put this.var for every variable in an object? for explanations):
function abs(val){
if (!(this instanceof abs))
return new abs(val);
this.getName = function getName(){
return val.name;
};
}
module.exports = abs;
As for that concrete
thing, I don't understand why you need it at all - it doesn't seem to do much more than concrete = abs;
would do. However, the blueprint for inheritance would look like this:
var abs = require('./abs');
function concrete(val){
if (!(this instanceof concrete))
return new concrete(val);
abs.call(this, val);
}
concrete.prototype = Object.create(abs.prototype);
Upvotes: 1