You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript构造函数使用及canvas图片绘制异常问题咨询

问题原因

错误是由普通函数的this指向异常导致的:
你给sprite.onload赋值的是普通匿名函数,这类函数的this会在触发时绑定到事件触发对象也就是sprite图片实例,而不是你的Rectangle类实例。你要访问的this.scale、this.x、this.y都不存在于sprite实例上,值为undefined,计算宽高时得到NaN(非数字),属于非法的绘制参数,因此canvas不会生成任何内容。
你之前的版本能正常运行属于巧合:因为宽高用了固定数值3,且实例化时x/y都设为0,即使this.x/this.y取值异常也刚好符合绘制的默认取值逻辑,没有触发绘制失败。

修复方案

有三种常用的修复方式,任选其一即可:

方案1:用箭头函数做回调(最推荐)

箭头函数不会绑定独立的this,会继承外层作用域的this指向,也就是Rectangle类实例:

update() {
    var sprite = new Image();
    sprite.src = this.source;
    // 改成箭头函数
    sprite.onload = () => {
        ctx.drawImage(sprite, this.x, this.y, sprite.width/this.scale, sprite.height/this.scale);
    }
}

方案2:外层缓存this指向

在普通函数外层提前把类实例的this存为临时变量,回调里直接用临时变量访问属性:

update() {
    // 提前缓存类实例的this
    const _this = this;
    var sprite = new Image();
    sprite.src = this.source;
    sprite.onload = function () {
        ctx.drawImage(sprite, _this.x, _this.y, sprite.width/_this.scale, sprite.height/_this.scale);
    }
}

方案3:用bind绑定this指向

通过bind方法手动把回调函数的this绑定为类实例:

update() {
    var sprite = new Image();
    sprite.src = this.source;
    sprite.onload = function () {
        ctx.drawImage(sprite, this.x, this.y, sprite.width/this.scale, sprite.height/this.scale);
    }.bind(this); // 绑定this指向
}

内容的提问来源于stack exchange,提问作者Damako

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:45:08