原型“this"不工作(JS)

Prototype "this" not working (JS)

本文关键字:工作 JS this quot 原型      更新时间:2023-09-26

尝试用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);
        };
    }
}

对于每个变量,在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值。可以通过使用callapplythis绑定到另一个值。

函数的this关键字的值由调用函数的方式设置。当drawImg方法在UI实例上被调用时,例如:

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

则在方法 fooi中。drawImgthis关键字将引用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 [path],这是函数的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);
    };