【发布时间】:2011-12-23 08:54:54
【问题描述】:
基本上有一个很好的优雅机制来模拟super,其语法与以下之一一样简单
-
this.$super.prop() this.$super.prop.apply(this, arguments);
坚持的标准是:
-
this.$super必须是对原型的引用。即,如果我在运行时更改超级原型,则将反映此更改。这基本上意味着父级有一个新属性,那么这应该在运行时通过super显示在所有子级上,就像对父级的硬编码引用会反映更改一样 -
this.$super.f.apply(this, arguments);必须适用于递归调用。对于在继承链上进行多次超级调用的任何链式继承集,您不能遇到递归问题。 - 您不能在您的孩子中硬编码对超级对象的引用。 IE。
Base.prototype.f.apply(this, arguments);说错了。 - 不得使用 X to JavaScript 编译器或 JavaScript 预处理器。
- 必须符合 ES5
天真的实现会是这样的。
var injectSuper = function (parent, child) {
child.prototype.$super = parent.prototype;
};
但是这个breaks condition 2。
迄今为止我见过的最优雅的机制是IvoWetzel's eval hack,它几乎是一个 JavaScript 预处理器,因此不符合标准 4。
【问题讨论】:
-
只是好奇,但是有什么理由为什么您需要在 JavaScript 中模拟
super?考虑到原型链的工作方式,我觉得它完全没有必要。 -
@zzzzBov
super只是用于代码重用的构造。这是我在 ES5 的 OO 糖中唯一缺少的东西。 ES6 带来了super,我很期待 -
您幼稚的实现也违反了标准 1。
-
injectSuper(P, C); x = new C(); C.prototype = {}; alert(x.$super.constructor === P); y = new C(); alert(y.$super === undefined);两者都为真。 -
@trinithis 当然可以。条件一只需反映对
P的更改。如果您覆盖C.prototype,那么它会中断。这是预期的行为,编写这样的代码很愚蠢
标签: javascript oop super