Is there a good template for calling JavaScript overridden functions in the parent without knowing the specific parent?

Basically, I want inherited functions, as in

Base = function() { }; Base.prototype.foo = function() { console.log("base foo"); }; Derived = function() { }; somelib.inherit(Derived, Base); Derived.prototype.foo = function() { console.log("derived foo"); } d = new Derived(): d.foo(); 

And I want him to print

 derived foo base foo 

Yes, I know that I can explicitly call Base.prototype.foo.call (this); I'm just wondering if there is a template for calling overridden superclass functions automatically. The problem I'm trying to solve is 2 times.

  • derived classes do NOT have to remember to call their parent method, it just happens automatically.
  • if 1. cannot happen, at least I would like Derived not to call Base by name, as it is fragile. Rather, I would like for him to call the parent class or something else, so you don't need to know the base. Thus, if you change the name of the database, you do not need to correct each derived class.
+8
javascript
source share
6 answers

You can implement this functionality using the following structure:

 function Base(){} Base.prototype.destroy = function(){console.log('Base destroy');}; function Derived(){} Derived.prototype = new Base; // Let Derived inherit from Base // Override the `destroy` method Derived.prototype.destroy = function() { console.log('Derived destroy'); // Call parent class method this.constructor.prototype.destroy(); // If the context of the method is important, you can use Function.call: //this.constructor.prototype.destroy.call(this); }; // Create an instance of Derived, and call the destroy method: (new Derived).destroy(); 
+2
source share

I would suggest thinking about why you are doing this, at least in terms of requirement # 1. Keep in mind that your desired template takes away more flexibility. For example, if you have a situation where you want to print instructions in reverse order:

  base foo derived foo 

You must either abandon your template or create a function foo2 () in a derived class that then calls foo () in the base class. Nothing really.

The same thing happens if you even want to do something simple:

  derived foo base foo one more thing in the derived function 

I would argue that using this pattern may work for the exact thing you want to do right now, but it can give you fits when you want to make an apparently trivial change in the future. All to save one line of code!

+2
source share

As far as I know, JavaScript does not have a language integrated destructor function. It's about wireframes. For example, if you use ASP.NET Ajax, the infrastructure will expect your objects to have the dispose method responsible for freeing resources (event handlers). So it is up to you.

0
source share

Well, this is not exactly what you are looking for, as it is not a β€œtemplate”, but it is a potential implementation path that you could follow:

Check out the @ package MooTools Class.Extras (for lack of a better word). Using the Chain class, you can probably get the functionality you want.

0
source share
 var parent = (function () { var construct = function () { }; construct.prototype = { constructor: construct, destroy: function () { console.log('parent destruction'); } } return construct; })(); var child = (function (parent) { var construct = function () { }; construct.prototype = Object.create(parent.prototype); construct.prototype.constructor = construct; construct.prototype.destroy = function () { parent.prototype.destroy.call(this); // calling parent, too console.log('child destruction'); }; return construct; })(parent); child_instance = new child(); child_instance.destroy(); 
0
source share

I would prefer that I don't assign Derived = chainify (), so the api would be the same as yours in your question, but at the moment this is the best way to make it work. It works by replacing each method of an object with a method that calls the replaced method and moves along the parent chain, invoking their methods on that path.

 function chainify() { return function () { var property; for (property in this) { if (typeof this[property] === "function") { this[property] = chain(this[property], property); } } function chain(method, method_name) { return function() { method(); var current = this; while (current = current.parent) { if (current.hasOwnProperty(method_name)) { current[method_name].apply(this, arguments); } } }; } } } var somelib = function() { }; somelib.inherit = function (derive, base) { derive.prototype = new base; derive.prototype.parent = base.prototype; }; var Base = function() { }; Base.prototype.foo = function() { console.log("base foo"); }; var Derived = chainify(); somelib.inherit(Derived, Base); Derived.prototype.foo = function() { console.log("derived foo"); }; d = new Derived(); d.foo(); 
0
source share

All Articles