为什么对象属性已更改为所有实例?

时间:2012-12-11 13:49:34

标签: javascript

我想将精灵的位置封装在另一个对象中。因此,我不会使用tile.xtile.y来访问tile.position.xtile.position.y

然而,一旦我在init-method all 中设置了tile.position的值,tile-object的实例就会变为相同的值。那是为什么?

当我设置tile.x时,一切都按预期工作,意味着每个对象都获得正确的值。

这是我创建多个实例的方式:

在for循环中,我创建了所述对象的多个实例:

for (var y = 0; y < 10; ++y) {
  for (var x = 0; x < 10; ++x) {
    var tile = Object.create(tileProperty);
    tile.init(x, y);
    ...
  }
}

这是克隆的对象:

var tileProperty = {
    // this works
    x: null, 
    y: null,
    // this will get changed for ALL instances
    position: { 
        x: null,
        y: null
    },
    init: function(x, y) {
        this.name = x.toString() + y.toString();
        this.x = x;
        this.y = y;
        this.position.x = x;
        this.position.y = y;
        this.canvas = document.createElement('canvas');
        var that = this;
        $(this.canvas).bind('click', function() {
            console.log(that.position, that.x, that.y);
        });

        document.body.appendChild(this.canvas);
    }
}

2 个答案:

答案 0 :(得分:1)

您在所有对象中都引用了相同的position对象。

您应该使用standard prototype solution

function tileProperty() {
    this.position = { 
        x: null,
        y: null
    };
}
tileProperty.prototype.init = function(x, y) {
    this.name = x.toString() + y.toString();
    this.x = x;
    this.y = y;
    this.position.x = x;
    this.position.y = y;
    this.canvas = document.createElement('canvas');
    var that = this;
    $(this.canvas).bind('click', function() {
        console.log(that.position, that.x, that.y);
    });

    document.body.appendChild(this.canvas);
}

然后使用

构建您的实例
var tp = new tileProperty();

答案 1 :(得分:1)

使用此:

var tileProperty = {
    position: { // we will inherit from this
        x: null,
        y: null,
        init: function(x, y) {
            this.x = x;
            this.y = y;
        }
    },
    init: function(x, y) {
        this.name = x.toString() + y.toString();
        // create an own Position object for each instance
        this.position = Object.create(this.position);
        // and initialize it
        this.position.init(x, y); // you might inline this invocation of course
        …
    },
    …
}