原型“这个”不起作用(JS)

时间:2011-09-08 02:33:05

标签: javascript canvas prototype-programming

尝试使用Image()对象执行.onload方法,显然它不会在其函数中继承“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 个答案:

答案 0 :(得分:3)

对于每个变量,在JavaScript中,this的范围与您所在的函数有关。因此,在

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

this将绑定到对象imgcache[path]。一种常见的方法是将this的值保存在另一个变量中(按惯例,通常是that),以便在嵌套函数中访问它:它被称为closure

var that = this;

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

现在,这是由于JavaScript如何绑定函数调用的this值。可以使用callapplythis绑定到其他值。

答案 1 :(得分:0)

函数的 this 关键字的值由函数的调用方式设置。在UI实例上调用 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);
    };

第一个 this 将引用 fooUI 。但是,分配给 onload 属性的匿名函数被称为 this.imagecache [path] 引用的对象的方法,因此该函数引用的对象是这个在被叫时。

你可以通过使用一个带有合理名称的局部变量的闭包来改变它( 在我看来不是一个好的选择),如:

    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);
    };