JavaScript中对象作为函数参数传递后变为undefined的问题
Pong游戏animate函数参数变undefined的原因及解决办法
核心问题:requestAnimationFrame调用时未传递指定参数
你第一次手动调用animate(canvas, ctx, ...)时参数是正常的,但动画循环里用requestAnimationFrame(animate)时,这个方法默认只会给回调传一个时间戳参数,不会自动带上你需要的canvas、ctx这些对象。等第二次执行animate的时候,原参数位置被时间戳占据,其他参数全变成undefined,自然就报clearRect的错误。递归调用遗漏参数
如果你的animate函数最后是靠requestAnimationFrame(animate)来维持循环,这里根本没把初始化的对象传进去,下次执行animate时所有参数都取不到,ctx就成了undefined。
解决办法
用闭包省掉传参(最推荐)
把animate函数放到start_game函数内部,作为内部函数,这样它可以直接访问start_game里初始化的canvas、ctx、ball等变量,不用手动传参:function start_game() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const ball = { /* 球的属性定义 */ }; const pad1 = { /* 左侧 paddle 属性定义 */ }; const pad2 = { /* 右侧 paddle 属性定义 */ }; function animate() { // 直接使用ctx等变量,无需传参 ctx.clearRect(0, 0, canvas.width, canvas.height); // 游戏绘制、逻辑代码... requestAnimationFrame(animate); } animate(); // 启动动画循环 }强制传递参数
如果一定要保留传参的写法,递归调用时用匿名函数包裹,确保每次都把所有参数传进去:function animate(canvas, ctx, ball, pad1, pad2) { ctx.clearRect(0, 0, canvas.width, canvas.height); // 游戏逻辑代码... // 递归调用时手动传入所有参数 requestAnimationFrame(() => animate(canvas, ctx, ball, pad1, pad2)); } function start_game() { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const ball = { /* 属性定义 */ }; const pad1 = { /* 属性定义 */ }; const pad2 = { /* 属性定义 */ }; animate(canvas, ctx, ball, pad1, pad2); // 第一次调用 }检查变量作用域
确认start_game里初始化的对象没有被意外销毁、重定义,或者被声明成了局部作用域外无法访问的变量。
内容的提问来源于stack exchange,提问作者Byzthr
相关产品推荐
相关产品推荐

