更新一个JavaScript对象就会更新所有对象

Updating one JavaScript object updates them all

本文关键字:对象 更新 一个 JavaScript      更新时间:2023-09-26

我有一个脚本,在画布上生成x数量的蝴蝶,我使用一些适度原始的函数构造器,以便每个蝴蝶可以被修改而不影响任何其他,但在更新一个序列时,它更新所有的序列,我看不出为什么。

由于代码的绝对数量(超过350行),我创建了一个JS小提琴来查看(可能会皱眉)

你可以在这里查看全部内容。

但是因为我不能发布一个链接到JSFiddle,这里是序列函数本身的代码。

function Sequence (s, f) {
    // Check we have arguments
    if (!s || !f) {
        throw new TypeError('No sequences to load');
    }
    // Instance for the onload event
    var _sq  = this;
    // Some public properties
    this.w  = 0;
    this.r  = false;
    this.st = 0;
    this.ns = 22;
    // This is the step in the sequence we're at
    this.s  = 20;
    // The step width
    this.sw = 0;
    // Create the image
    this._s = new Image;
    this._f = new Image;
    // Load listener 
    this._s.onload = function () {
        // Set our publics
        _sq.w = this.width;
        _sq.sw = _sq.w / fps;
    };
    this._s.src = s;
    this._f.src = f;
    // Return
    return this;
};

[编辑]我已经更新了序列类基本上不关心加载,它是预取的使用

<link rel="prefetch" href="image.png" />

我还更新了JSFiddle,以便您可以看到它的工作(还有其他几个更新),但代码有点笨拙,因此我不会深入讨论。

正如在注释中已经提到的,代码很难阅读。

但你的问题很可能在这里:

    for ( ; i < no_of_butterflies; i++) {
        // Create the sequence
        var s = new Sequence('http://ok5.com/blue-walking.png', 'http://ok5.com/blue-flying-2.png');
        // Listen to the load
        s.loaded = function() {
            bs.push(new Butterfly(s));
        };
        // Load the beast up
        s.load();
    }

在加载图像时调用s.loaded回调。你们所有的蝴蝶都有相同的Sequence从序列中取出状态和图像。我不能告诉你为什么其余的代码似乎工作,我真的没有时间调试你的代码。我的建议是阅读有关作用域和闭包的内容,然后重写一遍,因为我认为这样的问题更多。

编辑修复方法是将Sequence作为参数传递:

// If we have a loaded listener, fire it
if (_sq.loaded) {
    _sq.loaded(_sq);
}

并将回调更改为:

// Listen to the load
s.loaded = function(s) {
    bs.push(new Butterfly(s));
};

但是你必须检查它是否工作正确。