如何在javascript中使用新属性扩展现有类?

时间:2014-05-08 15:14:36

标签: javascript html5 inheritance overwrite easeljs

我使用库支持画布绘图(easelJS),我还是javascript的新手。该库使用以下“类”层次结构:

-DisplayObject

---容器

---形状

---位图

现在,我想要的是实现一些额外的功能,如简单的物理引擎。我希望所有的DisplayObjects(以及容器之类的后代)拥有它自己的附加属性实例,例如velocity

当我尝试:

DisplayObject.prototype.velocity = new Vector2d();

似乎所有实例都具有相同的速度,即使稍后在我的代码中我做了如下命令:

someShape.velocity.x = newValueX;    
someShape.velocity.y = newValueY;

我知道这个问题的一些解决方案,但它对我不满意:

  1. 我可以制作很多类: MyShape(扩展Shape),MyContainer(扩展容器)等,在他们的构造函数中我可以放this.velocity = new Vector2d();

  2. 我可以在下载后编辑DisplayObject的构造函数,就在库文件中(糟糕的解决方案!)

  3. 我记得在创建对象后立即在运行时添加这些属性(甚至更糟糕!) someShape = new Shape() someShape.velocity = new Vector2d(); // 15 other properties here

  4. 或者我可以将功能添加到DisplayObject的原型中 DisplayObject.prototype.exdendWithAdditionalProperties = new function(){ this.velocity = new Vector2d(); // 15 other properties here } 我仍然需要记住在创建对象后手动调用。

  5. 但对我来说似乎很多工作,我相信javascript可以提供更好的解决方案。

    请帮忙!

2 个答案:

答案 0 :(得分:1)

这不是一个真正的答案,但请记住,在JS中,原型和构造函数是一种特殊情况。

原型对象链中的父对象。当您调用构造函数时,它将使用实际原型创建一个新对象。

但所有这一切都不是必需的,你可以这样做:

function CustomShape() {
    var obj = new DisplayObject();
    obj.velocity = new Vector2d();
    return obj;
}

如果您想获得幻想,可以使用此解决方案将更多参数传递给构造函数:

https://stackoverflow.com/a/3362623/54606

由于我们并不确切知道您的需求,因此很难说。但请检查一下(Object.create)[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create]

你可以这样做:

function MyCustomShape() {
   var obj = Object.create(DisplayObject.prototype);
   // more construction
   obj.velocity = new Vector2d();
   return obj;
}

与前一个函数的区别在于,这个函数从不调用DisplayObject构造函数。您必须自己执行此操作,或使用.apply.call以及一些参数调用构造函数。

答案 1 :(得分:0)

的问题
DisplayObject.prototype.velocity = new Vector2d();

是,如果DisplayObject实例没有自己的velocity属性,它将从原型中继承该属性。

当你使用

someShape.velocity.x = newValueX;
someShape.velocity.y = newValueY;

你只是改变原型。

相反,您可以使用

someShape.velocity = new Vector2d();
someShape.velocity.x = newValueX;
someShape.velocity.y = newValueY;

但我会在构造函数中执行:

this.velocity = new Vector2d();