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

JavaScript中对象作为函数参数传递后变为undefined的问题

Pong游戏animate函数参数变undefined的原因及解决办法
  • 核心问题:requestAnimationFrame调用时未传递指定参数
    你第一次手动调用animate(canvas, ctx, ...)时参数是正常的,但动画循环里用requestAnimationFrame(animate)时,这个方法默认只会给回调传一个时间戳参数,不会自动带上你需要的canvas、ctx这些对象。等第二次执行animate的时候,原参数位置被时间戳占据,其他参数全变成undefined,自然就报clearRect的错误。

  • 递归调用遗漏参数
    如果你的animate函数最后是靠requestAnimationFrame(animate)来维持循环,这里根本没把初始化的对象传进去,下次执行animate时所有参数都取不到,ctx就成了undefined。

解决办法

  1. 用闭包省掉传参(最推荐)
    把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(); // 启动动画循环
    }
    
  2. 强制传递参数
    如果一定要保留传参的写法,递归调用时用匿名函数包裹,确保每次都把所有参数传进去:

    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); // 第一次调用
    }
    
  3. 检查变量作用域
    确认start_game里初始化的对象没有被意外销毁、重定义,或者被声明成了局部作用域外无法访问的变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:35:45