0

对不起,如果它是微不足道的,但我是一个非常初学者。在 Javascript 中,用类本身的属性扩展已经定义的对象类的最佳方法是什么?例如,假设我有一个Sprite带有一些内置属性和方法的类。我想要一个额外的属性Sprite.position,其中position部分是具有(比如说)两个属性position.xposition.y. 我希望它应用类的所有实例Sprite(过去和未来),而不是单个实例。如果position是一个简单的输入数据(数字或字符串),那么我可以只写Sprite.prototype.position='there'. 此外,如果position是一个数组,它会很容易:只需 write 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也被赋予position.x类Sprite 的每个istance 的属性。command 不会发生Sprite.prototype.position='there'这种情况,在这种情况下,每个 istance 都将拥有并保留自己的单独值。我希望每个位置都有单独的独立“位置”对象。

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

4

1 回答 1

1

And I want it applied all the instances of the class Sprite (past and future), not to one single instance.

You're quite right that if you were dealing with a primitive (like your "testing" string), you could just add it to Sprite.prototype and it would appear on all Sprite objects without any crosstalk between them.

Also if position was an array it would have been easy: just write Sprite.prototype.position=[0,0]

While it's true that the array would show up on all Sprite objects, they would have the potential for cross-talk, because they'd all share the same array:

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

If you don't mind them all sharing the same array/object, you can do exactly the same thing with your class:

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

Again, they will all share one Position object.

If you want each sprite instance to have its own Position object (or array), independent of the one on other instances, you have only two choices:

  1. Modify the Sprite constructor to assign the object/array to the instances as they're created.

  2. Spin through all Sprite objects ever created and add the object/array.

Obviously you can't do #2 unless you have references to those objects.


It may well be that you don't have to do anything to Sprite.prototype at all, depending on how you want to handle a sprite not having a position. For example:

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

Similarly, any time you want to get a sprite's position:

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

That will give you undefined if the sprite doesn't have a position yet.


A final option for you: Make position a function:

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;
    }
};
于 2013-07-21T09:16:20.153 回答