【问题标题】:js -Uncaught TypeError: Cannot read property 'x' of undefined at object (balljs -Uncaught TypeError:无法读取对象未定义的属性“x”(球
【发布时间】:2019-09-29 23:50:30
【问题描述】:

您好,我在尝试运行此代码时收到上述错误消息,但我终其一生都无法弄清楚它有什么问题,非常感谢您的帮助。请原谅您可能会看到的任何新手错误。我已经创建了一个球,我正在尝试移动它。


        class Ball{
            constructor(x,y,xSpeed,ySpeed,r){
                this.x =x;
                this.y=y;
                this.xSpeed=xSpeed;
                this.ySpeed=ySpeed;
                this.r= r;

            }

            draw(){
                ctx.clearRect(0,0, 500, 200);
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
                ctx.stroke();
             }

             move()
             {
                this.x+=this.xSpeed; //error is here
                this.y+=this.ySpeed;
                if (this.x==0)
                {
                    this.xSpeed=2;
                }
                else if(this.x==500)
                {
                    this.xSpeed=-2;
                }
                if (this.y==200)
                {
                    this.ySpeed=-1;
                }
                else if (this.y==0)
                {
                    this.ySpeed=1;
                }


                window.requestAnimationFrame(this.move);

            }
        }
    var canvas = document.getElementById("canvas-for-ball");
    var ctx = canvas.getContext("2d")
    let balls=new Ball (10,10,2,1,5);
    balls.draw();
    balls.move();

【问题讨论】:

  • window.requestAnimationFrame(this.move.bind(this));

标签: javascript class object


【解决方案1】:

问题在于,当您调用 requestAnimationFrame 并将对 move 的引用作为其回调传递给它时,执行回调时,绑定到您的 Ball 实例的 this 会丢失。相反,您必须以 this 仍绑定到您的 Ball 实例的方式传递 move。您可以通过使用.bind() 方法传递函数引用来做到这一点,该方法接受一个参数来指定回调函数运行时this 绑定的内容。

class Ball {
  constructor(x,y,xSpeed,ySpeed,r){
    this.x = x;
    this.y = y;
    this.xSpeed = xSpeed;
    this.ySpeed = ySpeed;
    this.r = r;
  }

  draw(){
    ctx.clearRect(0,0, 500, 200);
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
    ctx.stroke();
  }

  move(){
    this.x += this.xSpeed;
    this.y += this.ySpeed;
    if (this.x == 0) {
      this.xSpeed = 2;
    } else if(this.x == 500) {
      this.xSpeed =- 2;
    }
                
    if (this.y == 200) {
      this.ySpeed =- 1;
    } else if (this.y == 0) {
      this.ySpeed = 1;
    }
    window.requestAnimationFrame(this.move.bind(this));
  }
}

var canvas = document.getElementById("canvas-for-ball");
var ctx = canvas.getContext("2d")
let balls = new Ball(10,10,2,1,5);
balls.draw();
balls.move();
<canvas id="canvas-for-ball"></canvas>

【讨论】:

  • 感谢您的回复,这确实消除了错误,但实际上并没有让球移动,有什么建议吗?
  • @John 你需要再次调用 draw() 因为 move 只会更新坐标。
猜你喜欢
  • 2021-11-02
  • 2021-04-28
  • 2013-02-09
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 2020-03-28
  • 2023-04-11
  • 2016-04-22
相关资源
最近更新 更多