简体   繁体   English

JS类的多个实例

[英]Multiple Instances of JS Class

I got the following "Enemy" Class in JavaScript: 我在JavaScript中获得了以下“敌人”类:

function Enemy(position, rotation) {
    this.name = null;

    this.enemyForm = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: 20,
        height: 20,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 1
    });
    this.setX(position.posX);
    this.setY(position.posY);
    this.setRotation(rotation);
    this.setOffset(10, 10);
    this.add(this.enemyForm);
}

Enemy.prototype = new Kinetic.Group();

As you can see, i extend a Kinetic.Group for that because the Enemies will have some more Kinetic Elements and not just a Rectangle. 如您所见,我为此扩展了Kinetic.Group,因为敌人将具有更多的动力学元素,而不仅仅是矩形。

Now i create some Instances of that "Class" and add them to the game layer: 现在,我创建该“类”的一些实例,并将其添加到游戏层:

 var enemy1 = new Enemy({posX: 50, posY: 50}, 0);
 this.layer.add(enemy1);
 var enemy2 = new Enemy({posX: 100, posY: 100}, 0);
 this.layer.add(enemy2);
 var enemy3 = new Enemy({posX: 200, posY: 200}, 0);
 this.layer.add(enemy3);

The problem: Every Enemy gets the position of "enemy3", and not their own. 问题是:每个敌人都获得“ enemy3”的职位,而不是他们自己的职位。 So, every Enemy will be drawn at position "200, 200". 因此,每个敌人将在位置“ 200、200”处被吸引。 Now if i try this without inheritance, it works fine: 现在,如果我在没有继承的情况下尝试使用它,则效果很好:

function Enemy(position, rotation) {
    this.name = null;
    this.enemyForm = new Kinetic.Group();

    var rect = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: 20,
        height: 20,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 1
    });
    this.enemyForm.setX(position.posX);
    this.enemyForm.setY(position.posY);
    this.enemyForm.setRotation(rotation);
    this.enemyForm.setOffset(10, 10);
    this.enemyForm.add(rect);
}

Can anyone tell me what i am missing, and why i don´t get separate objects with the first method? 谁能告诉我我所缺少的,为什么我用第一种方法没有得到单独的对象?

No problem subclassing the Kinetic.Group: 继承Kinetic.Group没问题:

// a bunch of code from 
// http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.6.0.min.js

//optionally a config object can be passed to the constructor
//http://kineticjs.com/docs/Kinetic.Group.html
var Test = function(config){
  Kinetic.Group.call(this,config);
};
Test.prototype=Object.create(Kinetic.Group.prototype);

var test = new Test();

for(s in test){
  console.log(s);
}

I never look at the code of kinetic group. 我从不看动力学组的代码。 But this problem could happen if the code uses closure to create private variables like this: 但是,如果代码使用闭包来创建如下私有变量,则可能会发生此问题:

Kinetic.Group = function(){
    var setX, getX;
    (function() {
       var X = 0;
       getX = function(){
          return X ;
       };
       setX = function(v){
          X = v;
       };
     })();

    this.setX = setX;
    this.getX = getX;
}

When you declare Enemy.prototype = new Kinetic.Group(); 当您声明Enemy.prototype = new Kinetic.Group(); , there is only 1 Kinetic.Group created . 仅创建1个Kinetic.Group When you call this.setX(position.posX); 当您调用this.setX(position.posX); inside function Enemy(position, rotation) , because this function does not exist in the current instance, it will look up that function in the prototype property (the same Kinetic.Group for all your Enemy ) . function Enemy(position, rotation) ,因为此函数在当前实例中不存在,它将在prototype属性(所有Enemy的相同Kinetic.Group )中查找该函数。 All your instances created by the constructor function share the same variable var X = 0; 构造函数创建的所有实例共享相同的变量var X = 0; captured by the closure . 被封锁俘获

In your second case, this does not happen because you create a new Kinetic.Group for each Enemy . 在第二种情况下,不会发生这种情况,因为您为每个Enemy创建了一个新的Kinetic.Group

Update: (after taking a look at the code of Kinetic.Group 更新:(看一下Kinetic.Group的代码后

In the code, I see the case is different. 在代码中,我看到情况有所不同。 Each Kinetic.Group maintains a this.attrs = {}; 每个Kinetic.Group维护一个this.attrs = {}; for all your properties and the setX , getX are methods defined on Kinetic.Group.prototype => all your Enemy instances share the same attrs of a Kinetic.Group instance when you use Enemy.prototype = new Kinetic.Group(); 您的所有属性和setXgetX上定义的方法Kinetic.Group.prototype =>所有的敌人实例共享相同attrs一个的Kinetic.Group当您使用实例Enemy.prototype = new Kinetic.Group();

I'm afraid that you cannot use inheritance with this code. 恐怕您不能在此代码中使用继承。

I think if you want to have inheritance in javascript you should also call Group constructor in Enemy constructor. 我想,如果您想在javascript中继承,也应该在Enemy构造函数中调用Group构造函数。 Write it like this: 像这样写:

function Enemy(position, rotation) {

    // it create properties(and probably functions) on with Kinetic.Group depends
    // you could also pass x, y, rotation and offset in argument of this constructor
    Kinetic.Group.apply(this, [{}]);        

    this.name = null;
    this.enemyForm = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: 20,
        height: 20,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 1
    });
    this.setX(position.posX);
    this.setY(position.posY);
    this.setRotation(rotation);
    this.setOffset(10, 10);
    this.add(this.enemyForm);
}

Enemy.prototype = new Kinetic.Group();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM