admin管理员组文章数量:1290066
Basically I want inheritable 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 it to print
derived foo
base foo
Yes I know I can explicitly call Base.prototype.foo.call(this); I'm just wondering if there is a pattern for calling overridden super class functions automatically. The problem I'm trying to solve is 2 fold.
- derived classes should NOT have to remember to call their parent's method, it just happens automatically.
- if 1. can't happen then at least I'd like Derived not to call Base by name since that's brittle. Rather I'd like it call parentclass or something so you don't have to know the base. That way if you change the name of the base you don't have to go fixing every derived class.
Basically I want inheritable 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 it to print
derived foo
base foo
Yes I know I can explicitly call Base.prototype.foo.call(this); I'm just wondering if there is a pattern for calling overridden super class functions automatically. The problem I'm trying to solve is 2 fold.
- derived classes should NOT have to remember to call their parent's method, it just happens automatically.
- if 1. can't happen then at least I'd like Derived not to call Base by name since that's brittle. Rather I'd like it call parentclass or something so you don't have to know the base. That way if you change the name of the base you don't have to go fixing every derived class.
- How often do you really need a destructor in Javascript, anyway? – Karl Knechtel Commented Aug 25, 2011 at 11:19
- You need it in long running applications e.g. refreshing its data by ajax calls. In order to avoid problems it might make sense to dispose (unlink) events and callbacks when an object is no longer needed (memory leaks). I am looking for a pattern as well. – Horst Walter Commented Sep 22, 2011 at 12:31
-
Prototype.js eases the definition of such methods :
var Derived = Class.create(Base, { dispose: function($super) { $super(); ... subclass disposal code ...; } });
. It's not automatic, though. – Francois Commented Feb 21, 2012 at 12:46 - 1 Your question is difficult to answer because you say, "is there a good pattern..." when what you want to do is bad functionality itself. There's a reason no other languages call their parent functions implicitly. You need to call it explicitly. Albiet there are handy wrappers that help make it easier so you can call Derived.prototype.foo = function() { base(); console.log("derived foo"); } – Dustin Graham Commented Mar 12, 2012 at 23:58
6 Answers
Reset to default 2You can implement such functionality by using a structure like:
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();
I would suggest thinking about exactly why you are doing this, at least in terms of requirement #1. Keep in mind that your desired pattern would take away a great deal of flexibility. For instance, if you have a situation where you want to print the statements in the opposite order:
base foo
derived foo
You would either have to abandon your pattern or create a function foo2() in the derived class which then calls foo() in the base class. Neither is very pretty.
Same goes if you even want to do something as simple as:
derived foo
base foo
one more thing in the derived function
I would contend that using this pattern may work for the exact thing you want to do right now, but may give you fits when you want to make a seemingly trivial change down the road. All to save one line of code!
As far as I know there is no language integrated destructor functionality in JavaScript. It is all about frameworks. If you are using ASP.NET Ajax, for example, the framework would expect that your objects would have a dispose method, responsible for freeing up resources (event handlers). So, it is up to you.
Ok, this isn't quite what you are looking for, in that it's not a "pattern", but it is a potential implementation path you could follow:
Take a look @ the MooTools Class.Extras package (for lack of a better word). Using the Chain Class, you could probably get the desired functionality.
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();
I would prefer a way where I don't assign Derived = chainify() so that the api would be the same as you had in your question but as of right now this is the best way I can get it to work. It works by replacing each method of the object with a method that calls the replaced method and travels up the parent chain calling their methods along the way.
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();
本文标签:
版权声明:本文标题:Is there a good pattern for JavaScript calling overridden functions in a parent without knowing the specific parent? - Stack Ove 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741490049a2381577.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论