Reputation: 23
I'm having a bit of a dilemma getting my head around JS' prototypal inheritance. What I'm trying to do is:
Define an object called mod
var mod = function() {
function sayGoodbye() {
alert("Goodbye!");
}
function saySomethingElse(message) {
alert(message);
}
return {
sayGoodbye: sayGoodbye,
saySomethingElse: saySomethingElse
};
};
Define a prototype object called proto
var proto = {
sayHello: function() {
alert("Hello!");
}
};
Set the prototype of mod to proto
mod.prototype = proto;
Call a function that constructs a new instance of mod with the proto prototype
function construct(constructor, args) {
function constructorWrapper() {
return constructor.apply(this, args)
}
constructorWrapper.prototype = constructor.prototype;
return new constructorWrapper();
}
var foo = construct(mod, ["Other Message 1"]);
var bar = construct(mod, ["Other Message 2"]);
console.dir(foo);
console.dir(bar);
The construct function creates a new instance of mod correctly using the apply function but it's prototype is not proto. What am I missing that prevents mod from being constructed with proto as it's prototype?
Here is a fiddle with the above code.
Thanks heaps!!
Upvotes: 0
Views: 40
Reputation: 36
The reason the .prototype
assignment isn't working for you is because setting the prototype chain like this only works when you use the new
operator on a constructor function.
You created a factory function that returns a newly created object. Get rid of the return
in mod
and use this
to attach your method and use new
operator when creating instances of mod
will make the .prototype
assignment work.
This might be confusing so I updated your fiddle: https://jsfiddle.net/6fdo649y/1/
There are several ways to achieve what you are trying to do, but this example explains why you don't see .prototype
work.
//Constructor function using this
function Mod(arg1) {
this.sayGoodbye = function sayGoodbye() {
alert("Goodbye!");
}
this.saySomethingElse = function saySomethingElse(message) {
alert(message);
}
this.arg1 = arg1;
};
var proto = {
sayHello: function() {
alert("Hello!");
}
};
Mod.prototype = proto;
function construct(constructor, args) {
function constructorWrapper() {
constructor.apply(this, args)
}
constructorWrapper.prototype = constructor.prototype;
return new constructorWrapper();
}
var foo = construct(Mod, ["Other Message 1"]);
var bar = construct(Mod, ["Other Message 2"]);
console.dir(foo === bar);
console.dir(foo);
console.dir(bar);
edited: added in passing the args through with apply.
Upvotes: 1