如何在JavaScript中调用类函数?

时间:2018-10-19 21:17:38

标签: javascript html ecmascript-6

JavaScript的新手,所以可能很简单。

遇到错误:

  

ball.html:46未捕获的SyntaxError:意外的标识符

为什么会这样?我是JavaScript新手。但是我尽力修复了所有问题。尝试删除function,但随后出现错误:

  

draw()函数未在repeatMe()函数中定义。

HTML和JavaScript:

<!DOCTYPE html>

<html>

  <head>
    <meta charset="UTF-8">
    <title>Canvas</title>

    <style type="text/css">
      body {
          background-color: white;
      }

      canvas { 
        border: 3px solid black; 
    }
    </style>

  </head>

  <body>

    <canvas id="canvas-for-ball" height="800px" width="800px"></canvas>

    <script type="text/javascript">
      // Gets a handle to the element with id canvasOne.
      var canvas = document.getElementById("canvas-for-ball");
      // Get a 2D context for the canvas.
      var ctx = canvas.getContext("2d");

      // The vertical location of the ball.
      var y = 10;
      var x = 10;
      var ballRadius = 3;
      var ySpeed = 1;

      class Ball {
        constructor(x, y, ballRadius, ySpeed) {
            this.x = x;
            this.y = y
            this.ballRadius = BallRadius;
            this.ySpeed = ySpeed;
        }//endConstructor

        function drawball() {
            ctx.beginPath();
            ctx.arc(x, y, ballRadius, 0, 2 * Math.PI);
            ctx.stroke();
        }//endDrawball

        function draw() {
            ctx.clearRect(1, 1, 800, 800);
            drawball(); 
        }//endDraw

        function move() {
            // Update the y location.
            y += ySpeed;
            console.log(y);
        }
      } //endBall


      // A function to repeat every time the animation loops.
      function repeatme() {
        // Draw the ball (stroked, not filled).
        draw();
        move();

        //catch ball at bottom
        if (y == 800)
        {
             ySpeed = 0;
        }

        window.requestAnimationFrame(repeatme);
      }

      // Get the animation going.
      repeatme();
    </script>

  </body>

</html>

4 个答案:

答案 0 :(得分:1)

您需要先了解这一点,然后再开始使用JavaScript。Classes in JavaScript以及OOPS编程的一些基本知识。

您面临的问题是调用一个不存在的函数。另外,您错误地创建了类,这不是在JavaScript中的类中创建函数的方式。 另外,您不能直接访问类函数,这就是它们在类中的原因。需要创建该类的对象,该对象将用于调用类函数。

更改为此:

class Ball {
    constructor(x, y, ballRadius, ySpeed) {
        this.x = x;
        this.y = y
        this.ballRadius = BallRadius;
        this.ySpeed = ySpeed;
    }//endConstructor

    drawball() {
        ctx.beginPath();
        ctx.arc(x, y, ballRadius, 0, 2 * Math.PI);
        ctx.stroke();
    }//endDrawball

    draw() {
        ctx.clearRect(1, 1, 800, 800);
        drawball(); 
    }//endDraw

    move() {
        // Update the y location.
        y += ySpeed;
        console.log(y);
    }
  } //endBall

  let Ball = new Ball(x, y, ballRadius, ySpeed);
  // Note this is constructor calling so pass value for these arguments here

// A function to repeat every time the animation loops.
function repeatme() {

    // Draw the ball (stroked, not filled).
    Ball.draw();
    Ball.move();

    //catch ball at bottom
    if (Ball.y == 800)
    {
         Ball.ySpeed = 0;
    }

    window.requestAnimationFrame(repeatme);
} 

强烈建议您在进入JavaScript之前先阅读几篇文档,因为它会与callsbackspromisesclosureshoisting以及其他内容混淆。

答案 1 :(得分:0)

这里存在一个问题,您正在尝试调用一些不存在的函数:

  function repeatme() {
    // Draw the ball (stroked, not filled).
    draw(); //<-- Where is this function?
    move(); //<-- Where is this function?

    //catch ball at bottom
    if (y == 800)
    {
         ySpeed = 0;
    }

    window.requestAnimationFrame(repeatme);
  }

我想您想使用属于ball类的功能。如果是这样,则需要衍生一个Ball的新实例,然后从那里访问函数...:

  function repeatme() {
    // Draw the ball (stroked, not filled).
    let ball = new Ball(x, y, ballRadius, ySpeed); //<--- create a new ball instance
    ball.draw(); //<-- invoke the function which resides on a ball
    ball.move(); //<-- invoke the function which resides on a ball

    //catch ball at bottom
    if (y == 800)
    {
         ySpeed = 0;
    }

    window.requestAnimationFrame(repeatme);
  }

“可能”修复了您的代码,但是这里还需要研究许多其他概念。例如,您有一些变量的作用域超出Ball的范围,但是在Ball类内部,您正在引用它们。因此,您实际上是在这里创建了一个闭合……可能是偶然的。

您应该只让Ball做事情,而没有所有这些范围变量……有点像这样:

// Gets a handle to the element with id canvasOne.
      var canvas = document.getElementById("canvas-for-ball");
      // Get a 2D context for the canvas.
      var ctx = canvas.getContext("2d");

//< -- Notice I removes these vars here, since we really just want to feed those into the constructor of a Ball...

      class Ball {
        constructor(x, y, ballRadius, ySpeed) {
            this.x = x;
            this.y = y
            this.ballRadius = ballRadius;
            this.ySpeed = ySpeed;
        }//endConstructor

        drawball() {
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.ballRadius, 0, 2 * Math.PI);
            ctx.stroke();
        }//endDrawball

        draw() {
            ctx.clearRect(1, 1, 800, 800);
            this.drawball(); 
        }//endDraw

        move() {
            // Update the y location.
            this.y += this.ySpeed;
            console.log(this.y);
        }
      } //endBall


      // A function to repeat every time the animation loops.
      function repeatme() {
        // Draw the ball (stroked, not filled).
         // The vertical location of the ball.  Remember the variables above?  Now the values are fed into here instead...
        let ball = new Ball(10, 10, 3, 1)
        ball.draw();
        ball.move();

        //catch ball at bottom
        if (ball.y == 800)
        {
             ball.ySpeed = 0;
        }

        window.requestAnimationFrame(repeatme);
      }

      // Get the animation going.
      repeatme();

答案 2 :(得分:0)

我刚刚在class()中定义了以下功能

function drawball() {
        ctx.beginPath();
        ctx.arc(x, y, ballRadius, 0, 2 * Math.PI);
        ctx.stroke();
    }//endDrawball

    function draw() {
        ctx.clearRect(1, 1, 800, 800);
        drawball(); 
    }//endDraw

    function move() {
        // Update the y location.
        y += ySpeed;
        console.log(y);
    }

更新后的工作代码:

<!DOCTYPE html>

<html>

  <head>
    <meta charset="UTF-8">
    <title>Canvas</title>

    <style type="text/css">
      body {
          background-color: white;
      }

      canvas { 
        border: 3px solid black; 
    }
    </style>

  </head>

  <body>

    <canvas id="canvas-for-ball" height="800px" width="800px"></canvas>

    <script type="text/javascript">
      // Gets a handle to the element with id canvasOne.
      var canvas = document.getElementById("canvas-for-ball");
      // Get a 2D context for the canvas.
      var ctx = canvas.getContext("2d");

      // The vertical location of the ball.
      var y = 10;
      var x = 10;
      var ballRadius = 3;
      var ySpeed = 1;

      class Ball {
        constructor(x, y, ballRadius, ySpeed) {
            this.x = x;
            this.y = y
            this.ballRadius = BallRadius;
            this.ySpeed = ySpeed;
        }//endConstructor

      } //endBall

        function drawball() {
            ctx.beginPath();
            ctx.arc(x, y, ballRadius, 0, 2 * Math.PI);
            ctx.stroke();
        }//endDrawball

        function draw() {
            ctx.clearRect(1, 1, 800, 800);
            drawball(); 
        }//endDraw

        function move() {
            // Update the y location.
            y += ySpeed;
            console.log(y);
        }
      // A function to repeat every time the animation loops.
      function repeatme() {
        // Draw the ball (stroked, not filled).
        draw();
        move();

        //catch ball at bottom
        if (y == 800)
        {
             ySpeed = 0;
        }

        window.requestAnimationFrame(repeatme);
      }

      // Get the animation going.
      repeatme();
    </script>

  </body>

</html>

答案 3 :(得分:0)

问题的根源在于您正在创建一个类,但从未创建该类的实例来调用您的函数。这是一个经过清理的功能示例,其中带有注释,解释了事情的不同之处。

// Gets a handle to the element with id canvasOne.
var canvas = document.getElementById("canvas-for-ball");
// Get a 2D context for the canvas.
var ctx = canvas.getContext("2d");

// The vertical location of the ball.
var y = 10;
var x = 10;
var ballRadius = 3;
var ySpeed = 1;

class Ball {
  constructor(x, y, ballRadius, ySpeed) {
    // changed these to set the private members
    this._x = x;
    this._y = y
    // updated the assignment here, it had the wrong case
    this._ballRadius = ballRadius;
    this._ySpeed = ySpeed;
  } //endConstructor
  
  // added a setter for ySpeed so you can acess it outside of the class
  set VerticleSpeed(val){
    this._ySpeed = val;
  }
  
  // added a getter/setter for y so you can access it outside of the class
  get VerticlePosition(){
    return this._y;
  }
  
  // remove the function keyword, it's not needed
  drawball() {
    ctx.beginPath();
    // updated this to reference the properties on the class
    ctx.arc(this._x, this._y, this._ballRadius, 0, 2 * Math.PI);
    ctx.stroke();
  } //endDrawball

  // remove the function keyword, it's not needed
  draw() {
    ctx.clearRect(1, 1, 800, 800);
    this.drawball();
  } //endDraw

  // remove the function keyword, it's not needed
  move() {
    // Update the y location.
    // updated this to reference the properties on the class
    this._y += this._ySpeed;
    console.log("Ball position", this._y);
  }
} //endBall


// A function to repeat every time the animation loops.
function repeatme() {
  // Draw the ball (stroked, not filled).
  // upated to call the functions on the instance of the class
  myBall.draw();
  myBall.move();

  //catch ball at bottom
  // changed to check the property on the instance of the class
  // changed this bit to make it bounce and if its outside the bounds, this is just me showing off and having fun with this example
  
  if (myBall.VerticlePosition >= canvas.height) {
    // changed to assign the property on the instance of the class
    myBall.VerticleSpeed = -ySpeed;
  } else if (myBall.VerticlePosition <= 0){
    myBall.VerticleSpeed = ySpeed;
  }

  window.requestAnimationFrame(repeatme);
}

// create an instance of your class
let myBall = new Ball(x, y, ballRadius, ySpeed)
// Get the animation going.
repeatme();
body {
  background-color: white;
}

canvas {
  border: 3px solid black;
}

.as-console-wrapper {
  max-height: 25px !important;
}
<!DOCTYPE html>

<html>

<head>
  <meta charset="UTF-8">
  <title>Canvas</title>
</head>

<body>

  <canvas id="canvas-for-ball" height="150px" width="400px"></canvas>

</body>

</html>