Прототип "этот" не работает (JS) - PullRequest
2 голосов
/ 08 сентября 2011

Попытка сделать метод .onload с объектом Image (), и, очевидно, он не наследует «this» в своей функции.Любая помощь?

function UI() {
    this.canvas_obj = document.getElementById('game');
    this.canvas = this.canvas_obj.getContext('2d');
    this.imgcache = {};
    this.imglist = [
        'rooms/main-square.png'
    ];
    for (var i = 0; i < this.imglist.length ; i++) {
        var img = new Image();
        img.src = this.imglist[i];
        this.imgcache[this.imglist[i]] = img;
    }
}

// snip //

/*
 * drawImg
 * Draws an image on the canvas at the specified x, y (if the image isn't in the pre-cache, it creates it as well)
 * @param str   image path
 * @param array x,y
 * @param array width, height
 */
UI.prototype.drawImg = function(path, coords, size) {
    var found = false;
    if (size == undefined) {
        var w = 0;
        var h = 0;
    } else {
        var w = size[0];
        var h = size[1];
    }
    for (var i = 0; i < this.imgcache.length ; i++) {
        if (path == this.imgcache[i].src) {
            found = true;
        }
    }
    if (!found) {
        var img = new Image();
        img.src = path;
        this.imgcache[path] = img;
    }
    if (w == 0 && h == 0) {
        this.imgcache[path].onload = function() {
            this.canvas.drawImage(this.imgcache[path], coords[0], coords[1], this.imgcache[path].width, this.imgcache[path].height);
        };
    } else {
        this.imgcache[path].onload = function() {
            this.canvas.drawImage(this.imgcache[path], coords[0], coords[1], w, h);
        };
    }
}

Ответы [ 2 ]

3 голосов
/ 08 сентября 2011

Как и для каждой переменной, в JavaScript область действия this относится к функции, в которой вы находитесь. Поэтому, когда в

this.imgcache[path].onload = function() {
     // ...   
};

this будет привязан к объекту imgcache[path],Обычный подход заключается в том, чтобы сохранить значение this в другой переменной (обычно это that) для доступа к нему внутри вложенных функций: оно называется замыканием .

var that = this;

this.imgcache[path].onload = function() {
     // that will reference the "outer this"
};

Теперь это связано с тем, как JavaScript связывает значение this при вызове функции.Можно связать this с другим значением, используя call или apply.

0 голосов
/ 08 сентября 2011

Значение ключевого слова этого функции определяется тем, как вызывается функция.Когда метод drawImg вызывается для экземпляра пользовательского интерфейса, например:

var fooUI = new UI(...);
fooUI.drawImg(...);

, то в методе fooUI.drawImg , this ключевое слово будет ссылаться на fooUI .

Внутри метода есть присваивание свойству onload :

    this.imgcache[path].onload = function() {
        this.canvas.drawImage(this.imgcache[path], coords[0], coords[1],
                              this.imgcache[path].width, this.imgcache[path].height);
    };

Первый это будет ссылаться на fooUI .Однако анонимная функция, назначенная свойству onload , вызывается как метод объекта, на который ссылается this.imagecache [путь] , так что это объект, на который ссылается функция this при вызове.

Вы можете изменить это, используя замыкание на локальную переменную с разумным именем (, что, на мой взгляд, не является хорошим выбором), например:

    var uiObj = this;
    this.imgcache[path].onload = function() {
        uiObj.canvas.drawImage(uiObj.imgcache[path], coords[0], coords[1],
                               uiObj.imgcache[path].width, uiObj.imgcache[path].height);
    };
...