我如何将Raphael.st子类化

时间:2014-05-12 16:17:00

标签: javascript raphael subclassing

我的图表应用程序中有许多逻辑对象,每个逻辑对象都包含许多Raphael对象。例如,数据点可能包含圆圈和标题。

我希望能够将所有这些对象作为一个对象进行处理,并且还能够确定任何给定的Raphael元素属于哪个逻辑对象(例如,处理鼠标单击逻辑元素的上下文中的元素)它属于。。

我希望能够创建Raphael.st的子类(即Raphael集),并覆盖push方法以将element.data(" object")设置为包含逻辑对象。

在代码的其他地方,我使用以下子类方法(我在Stack Overflow上找到):

/**
 * Utility function to help subclassing
 * @param base
 * @param sub
 */
function subclass(base, sub) {
    // Avoid instantiating the base class just to setup inheritance
    // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
    // for a polyfill
    sub.prototype = Object.create(base.prototype);
    // Remember the constructor property was set wrong, let's fix it
    sub.prototype.constructor = sub;
    // In ECMAScript5+ (all modern browsers), you can make the constructor property
    // non-enumerable if you define it like this instead
    Object.defineProperty(sub.prototype, 'constructor', {
        enumerable: false,
        value: sub
    });
}

但是,此方法抛出异常,因为base = Raphael.st时base.prototype为null。

我为无知子类如何在javascript中真正起作用而道歉 - 我意识到盲目地从其他地方复制代码并不理想,但我还没有找到我理解的解释!

任何人都可以告诉我如何将Raphael.st分类,和/或指出我的解释方向,这将使我能够找到适合自己的方法吗?

1 个答案:

答案 0 :(得分:1)

将Raphael.set子类化并不是一个好主意,因为Raphael并不期待它。例如,Raphael中需要知道它是否处理集合的大量代码使用如下代码:

if (element.constructor == R.st.constructor)

这意味着一个合适的子类将无法通过测试。

如果您仍想继续(并且没有任何冲突属性或功能名称,就像我在尝试时所做的那样!),我确实找到了答案。

需要修改子类函数,因为Raphael不遵循通常的惯例 - Raphael.st不是类,它是类的原型。因此,子类方法应修改如下:

function subclass(base, sub) {
// Avoid instantiating the base class just to setup inheritance
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
// for a polyfill
sub.prototype = Object.create(base.prototype ? base.prototype : base);
// Remember the constructor property was set wrong, let's fix it
sub.prototype.constructor = sub;
// In ECMAScript5+ (all modern browsers), you can make the constructor property
// non-enumerable if you define it like this instead
Object.defineProperty(sub.prototype, 'constructor', {
    enumerable: false,
    value: sub
});
}

这是子类构造函数:

/**
 * @param paper Raphael Paper
 */
var MySet = function(paper) {
Raphael.st.constructor.call(this);
// Without this, Raphael does not recognise MySet objects as sets
// because it tests constructor value using == instead of instanceof
this.constructor = Raphael.st.constructor;
// Cheat!! Copied this code from Raphael Paper.set()
this.paper = paper;
};

subclass(Raphael.st, MySet);

希望这有助于其他人!