【问题标题】:How do I change the values of variables inside functions in Javascript?如何在 Javascript 中更改函数内部变量的值?
【发布时间】:2012-03-16 10:49:43
【问题描述】:

我正在尝试在 Javascript 中做更多的 OOP。 我想不通的一件事是如何从另一个函数修改对象内部的变量?

我是这样尝试的:

function Ball(){
    radius = 5;
    Y = 20;
    X = 25; // The value i would like to change.
    ctx.arc(this.X, this.Y, this.radius, 0, Math.PI*2, true);
    ctx.fillStyle = '#00ff00';
    ctx.fill();
}

function draw(){
    Player();
    Ball();
}

function update(){
    ctx.clearRect(0, 0, 800, 400);
    draw();
    Ball.X++;  // This is where i want to modify the value.

}

到目前为止,我只能将 X 定义为全局变量,但我不想这样做,因为还有其他 X 和 Y 值。

那么我如何从函数外部访问变量呢?

编辑: “nnnnnn”提供的解决方案在一定程度上起作用,它改变了 X 值,但我遇到了另一个问题。 我的 clearRect 不会清除动画,所以它画的不是一个球,而是一条刚刚增长的线。

这就是代码现在的样子:

function Ball(){
    this.radius = 5;
    this.Y = 20;
    this.X = 25;
    this.draw = function() {
       ctx.arc(this.X, this.Y, this.radius, 0, Math.PI*2, true);
       ctx.fillStyle = '#00ff00';
       ctx.fill();
    };
}

var ball = new Ball();

function draw(){
    Player();
    ball.draw();
}


function update(){
    ctx.clearRect(0, 0, 800, 400);
    draw();
    ball.X++;
}

我试过移动它,把它放在 draw() 和 ball.draw() 函数中,但仍然得到相同的结果,我也尝试做一个 fillRect 而不是 clear,但它没有帮助。 任何人都可以看到什么是错的?

【问题讨论】:

  • 没什么不好的感觉,但我宁愿先学走路再跑。您的代码看起来不是很有野心。您不是在处理实例/对象,您只是在函数中有变量(甚至不是本地变量)。
  • 是的,它们曾经是 this.X 和 this.Y 等,但由于它们是本地的,我试图让它们全局可变:D

标签: javascript oop


【解决方案1】:

“到目前为止,我只能将 X 定义为全局变量”

其实你的变量radiusXY变量都是全局变量。要使它们成为对象的属性,它们需要按如下方式设置:

someObject.radius = 5;
// OR
someObject["radius"] = 5;

它们不是 Ball() 函数中的局部变量,因为它们没有使用 var 声明 - 任何您在未使用 var 声明的情况下为其赋值的变量都会自动变为全局变量。

您的 Ball() 函数在您调用它时并未创建对象 - 为此您需要使用 new

var ball = new Ball();

如果你用new 调用它,那么JS 会自动创建一个Ball 的新instance,并在函数this 中引用该新实例。所以函数应该说:

function Ball(){
    this.radius = 5;
    this.Y = 20;
    this.X = 25; // The value i would like to change.
    ctx.arc(this.X, this.Y, this.radius, 0, Math.PI*2, true);
    ctx.fillStyle = '#00ff00';
    ctx.fill();
}

然后您可以按如下方式访问和更改属性:

var ball = new Ball();
alert(ball.X); // 25
ball.X++;

但是,这并不真正适合您构建代码的方式,因为您试图调用 Ball() 以使其自行绘制。你可能想要更多这样的东西:

function Ball(){
    this.radius = 5;
    this.Y = 20;
    this.X = 25;
    this.draw = function() {
       ctx.arc(this.X, this.Y, this.radius, 0, Math.PI*2, true);
       ctx.fillStyle = '#00ff00';
       ctx.fill();
    };
}

var ball = new Ball();

function draw(){
    Player();
    ball.draw();
}

function update(){
    ctx.clearRect(0, 0, 800, 400);
    draw();
    ball.X++;
}

【讨论】:

  • 谢谢你,这工作:)。我之前尝试过类似的东西,但无法让它运行。我仍然遇到一个问题,clearRect 不起作用,所以它不是一个 5 半径的球,而是画一条越来越长的线。我应该把 clearRect 放在哪里?
  • 我不确定 - 我想如果你总是在 draw() 之前调用 .clearRect() 在应该这样做的 update() 函数中。你能把演示发到jsfiddle.net吗?
【解决方案2】:

在 Ball 函数中,使用this.X = 25;。然后,当你实例化 Ball 时,你可以这样做

var ball = new Ball();
ball.X++;

更多信息在这里:OOP in JS, Part 1 : Public/Private Variables and Methods

【讨论】:

    【解决方案3】:

    创建一个 Ball 类型的实例,使用它的引用来修改实例变量。

    function update(){
        ctx.clearRect(0, 0, 800, 400);
        draw();
        var objBall = new Ball();
        objBall.X++
    }
    

    【讨论】:

    • 这需要this.X = 25; in Ball
    【解决方案4】:

    有几种方法可以做到这一点。首先,您可以通过在要在外部使用的变量的前面添加 this 关键字来使用构造方法。像这样:

    function Ball(){
      this.radius = 5;
      this.Y = 20;
      this.X = 25; // The way you wanted.
    
      ctx.arc(this.X, this.Y, this.radius, 0, Math.PI*2, true);
      ctx.fillStyle = '#00ff00';
      ctx.fill();
    }
    
    //call it like this 
    Ball.X;
    Ball.Y;
    Ball.radius;
    
    //or inside an assigned variable which is instantiated with 'new' keyword:
    var myVar = new Ball(); 
    myVar.X;
    myVar.Y;
    myVar.radius;
    

    或使用对象表示法,如下所示:

    var Ball = {
      radius: 5,
      Y: 20,
      X: 25,
    
      someFunction: function() {
        //Even in here use 'this' to refer to any property of the object 'Ball', like this:
        var product = this.radius * this.X;
    
        return product + this.Y
      }
    
    };
    
    //call it also this way
    Ball.X;
    
    //or
    Ball.radius;
    
    //or
    Ball.someFunction();
    

    现在可以在任何地方使用它:

    function update(){
      //Now you can use it anywhere
      var smallBall = new Ball();
      smallBall.X++;
    }
    

    所以如果你想让一个属性属于一个对象,请在构造函数中使用this,或者只使用对象表示法。您选择的技术取决于您想在项目中做什么。 此外,如果您想隐藏对象中的任何属性(即变量、函数等),请使用 var 关键字,以便该属性不是全局的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 2021-03-12
      • 2021-05-18
      • 2013-04-02
      • 2021-03-16
      • 2011-03-31
      相关资源
      最近更新 更多