在Javascript中将子类原型化为已定义的类

时间:2013-07-21 09:04:47

标签: javascript prototype subclass

对不起,如果它是微不足道的,但我是一个非常初学者。在Javascript中,使用类本身的propreties扩展已定义的对象类的最佳方法是什么? 例如,假设我有一个类Sprite,其中包含一些内置属性和方法。我希望有一个额外的属性Sprite.position,其中position部分是一个类(例如)两个属性position.xposition.y。我希望它应用类Sprite(过去和将来)的所有实例,而不是单个实例。 如果position是一个简单的输入数据(数字或字符串),那么我可以写Sprite.prototype.position='there'。此外,如果position是一个数组,那就很简单:只需编写Sprite.prototype.position="there",或者甚至数组数组都可以这样工作......但是如果position是一个类呢?通常要构建“类”,可以使用对象构造函数:

function position(x,y) {
    this.x = x;
    this.y = y;
 }

但是我需要使用position实例化var myPosition = new position(0,0);个对象,但我希望每次实例化一个新的Sprite对象时都存在位置对象。如果我写Sprite.prototype.position=new position(0,0);而不是有问题:如果我定义mySprite1.position.x=2,则值2也会被赋予Sprite类的每个属性的属性position.x。命令Sprite.prototype.position='there'不会发生这种情况,在这种情况下,每个istance将拥有并保留自己独立的值。我希望每个方面都有独立的“位置”对象。

是否有可能以简单的线性方式做我想要的事情?

1 个答案:

答案 0 :(得分:1)

  

我希望它应用类Sprite(过去和将来)的所有实例,而不是单个实例。

如果您正在处理原语(例如"testing"字符串),那么您可以将其添加到Sprite.prototype并且它会显示在所有Sprite个对象上它们之间没有任何串扰。

  

如果position是一个数组,那就很简单:只需写Sprite.prototype.position=[0,0]

虽然数组会显示在所有Sprite个对象上,但它们可能会产生串扰,因为它们都共享相同的数组:

var sprite1 = new Sprite();
var sprite2 = new Sprite();
Sprite.prototype.position = [0,0];
sprite1.position[0] = 42;
console.log(sprite2.position[0]); // "42"

如果你不介意他们共享相同的数组/对象,你可以对你的类做同样的事情:

Sprite.prototype.position = new Position(/*...*/);

同样,他们将共享一个 Position对象。

如果您希望每个精灵实例拥有其拥有 Position对象(或数组),与其他实例上的对象无关,则只有两个选择:

  1. 修改Sprite构造函数,将对象/数组分配给实例。

  2. 旋转所有创建的Sprite个对象并添加对象/数组。

  3. 显然你不能做#2除非你有这些对象的引用。


    您可能根本不需要对Sprite.prototype执行任何操作,具体取决于您希望如何处理没有position的精灵。例如:

    function doSomethingWithASprite(sprite) {
        if (!sprite.position) {
            // Doesn't have a position yet, give it one
            sprite.position = new Position(/*...relevant args...*/);
        }
    }
    

    同样,只要你想获得一个精灵的位置:

    var x = sprite.position && sprite.position.x;
    

    如果精灵还没有位置,那将给你undefined


    最后一个选项:让position成为一个功能:

    Sprite.prototype.position = function(x, y) {
        // Make sure we have a position
        if (!this.position) {
            this.position = new Position(/*...relevant args...*/);
        }
    
        if (typeof x === "undefined") {
            // Getter, return the current position
            return this.position;
        }
        else {
            // Setter, set the current position
            this.position.x = x;
            this.position.y = y;
        }
    };