JavaScript类中move方法获取sprites数组长度报错,redraw方法正常
问题:Canvas类的#move方法获取sprites.length报错,#redraw方法可正常运行
问题详情
在Canvas类的#move方法的for循环中获取sprites数组的length时会报错(提示length未定义),但#redraw方法中执行相同操作却正常。#redraw可以正确绘制方块,但#move函数无法正常运行。
代码示例
class Canvas { init() { this.canvas = document.getElementById("canvas"); this.ctx = canvas.getContext("2d"); this.sprites = []; // 存储每个精灵的x、y、r属性 this.active = false; } ball(r, clickMult, speed) { this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height); this.sprites.push({x: 0, y: 0, r: r, xVel: speed, yVel: speed}); this.#redraw(); if (!this.active) { setInterval(this.#move, 200); this.active = true; } } #redraw() { for (let i = 0; i < this.sprites.length; i++) { this.ctx.beginPath(); this.ctx.fillRect(this.sprites[i].x, this.sprites[i].y, this.sprites[i].r, this.sprites[i].r); this.ctx.fill(); this.ctx.closePath(); } } #move() { for (let i = 0; i < this.sprites.length; i++) { this.sprites[i].x += this.sprites[i].xVel; this.sprites[i].y += this.sprites[i].yVel; } this.#checkCollision(); this.#redraw(); } #checkCollision() { for (let i = 0; i < this.sprites.length; i++) { if (this.sprites[i].x < 0) { this.sprites[i].x = 0; this.sprites[i].xVel *= -1; } else if (this.sprites[i].x + this.sprites[i].r > this.canvas.width) { this.sprites[i].x = this.canvas.width - this.sprites[i].r; this.sprites[i].xVel *= -1; } if (this.sprites[i].y < 0) { this.sprites[i].y = 0; this.sprites[i].yVel *= -1; } else if (this.sprites[i].y + this.sprites[i].r > this.canvas.width) { this.sprites[i].y = this.canvas.width - this.sprites[i].r; this.sprites[i].yVel *= -1; } } } }
报错信息
Uncaught TypeError: Cannot read properties of undefined (reading 'length')
解决方案
核心原因
setInterval(this.#move, 200)调用时,#move方法的this指向不是Canvas类的实例,而是全局对象(浏览器环境下为window),导致this.sprites为undefined,无法读取length属性。
修复步骤
- 修正
this指向问题:- 方法一:使用箭头函数包裹,确保
this绑定到Canvas实例:setInterval(() => this.#move(), 200); - 方法二:使用
bind方法显式绑定this:setInterval(this.#move.bind(this), 200);
- 方法一:使用箭头函数包裹,确保
- 修复
init方法的小错误:
原代码中this.ctx = canvas.getContext("2d");未使用this访问canvas属性,会导致变量未定义错误,应修改为:this.ctx = this.canvas.getContext("2d");
内容的提问来源于stack exchange,提问作者Violet
相关产品推荐
相关产品推荐

