I've been given a class -
Zoo.Controller = (function() {
function Controller() {}
Controller.prototype.params = {};
Controller.prototype.set_params = function(params) {
this.params = params;
return this;
};
return Controller;
})();
and I want to inherit from that class using _.extend
Zoo.Controllers.WhaleController = _.extend({
new: function () {
// do something
}
}, Zoo.Controller);
When I try to instantiate that class like so...
this.whale_controller = new Zoo.Controllers.WhaleController();
I get -
Uncaught TypeError: object is not a function
Is it possible to do what I'm trying? I've read multiple articles on inheritance in JS, but had assumed that the Underscore library had it solved for me.
As others have explained, underscore's
extend
method creates (very) shallow copies of object instances and doesn't preserve prototype chains. However I recently came up against a small library — Compose.js — whose wider remit is to provide a more flexible API for JS's OO properties.The second example in the readme seems to deal with your use case almost exactly — I believe in your situation it would be invoked as follows:
John Resig has a good blog post on implementing Javascript inheritance that may be useful to you as it contains a solution for prototype inheritance, whereas Underscore
extend
is designed to extend simple Javascript objects.As Bergi pointed out; it isn't hard to inherit in JavaScript. You should know what a constructor function does and what prototype is used for. This answer may help with that, I tried to demonstrate prototype through simple and hopefully easy to understand examples. You can copy and paste the code in your browsers JS commandline (in the console) and change it to see if you understand how prototype behaves in JavaScript.
To inherit from ZooController you can:
Polyfill for Object.create here.
No, Underscore does have no helper functions for prototypical inheritance. Read the docs on what
extend
does:Most interestingly, it does not return a function, but its first argument (which is a plain object).
So get back to the articles you've read, and choose a framework that does actually have an
inherit
function or implement the inheritance yourself - it's not hard.You could reuse the
extend()
function used by backboneJs. Its a quite simple function that uses _.extend() toohttp://backbonejs.org/docs/backbone.html#section-208
Then attach it to your Controller prototype so you could do something like:
hope this helps
I was wondering this myself, and this is what I came up with.
Define the parent
Define the child
Construct a new a child to see the results
Console Results: