javascript对象,自引用问题

发布于 2024-10-23 13:42:24 字数 1919 浏览 1 评论 0原文

我刚刚开始在 javascript 中使用 oop,在尝试从另一个方法内部访问一个方法时遇到了一些问题。

这是我的代码:

var Game = {
initialize: function () {
    if (canvas.isSupported()) {
        sprites[0] = new Player();

        this.update();
    }
},

update: function() {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
},

draw: function() {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }

    setTimeout(this.update, 10);
},

clear: function() {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
}

}

但是调用 Game.update() 会给出一个错误,表明未定义绘制方法。 我找不到真正的解决方案。 最终我发现了这个 How to call a method inside a javascript object< /a> 答案似乎是我需要保护此引用,例如: var _this = this; 但我无法让它以文字表示法工作,所以我将代码更改为对象构造函数(我猜这就是它的调用方式)并添加了变量。

然后我改为

this.draw();

并且

_this.draw();

它起作用了。

尽管

this.clear();

和 this.update() 仍然相同,但它们似乎从来没有给出错误。

谁能解释这是为什么吗?也许给我指出一个更好的解决方案? 提前致谢。

更新

应该是这样的:

var Game = function () {
var _this = this;

this.initialize = function () {
    if (canvas.isSupported()) {
        sprites[0] = new Player();

        this.update();
    }
}

this.update = function () {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
}

this.draw = function () {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }


    setTimeout(function () { _this.update(); }, 10);
}

this.clear = function () {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
}

}

I just started using oop in javascript and I ran across some problems trying to acces a method from inside another method.

here's the code I had:

var Game = {
initialize: function () {
    if (canvas.isSupported()) {
        sprites[0] = new Player();

        this.update();
    }
},

update: function() {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
},

draw: function() {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }

    setTimeout(this.update, 10);
},

clear: function() {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
}

}

but calling the Game.update() gives an error that the draw method isn't defined.
I couldn't find a real solution for this.
eventually I found this How to call a method inside a javascript object
where the answer seems to be that I need to safe the this reference like:
var _this = this;
but I couldn't get that to work in literal notation, so I changed the code to object constructor (I guess that's how it's called) and added the variable.

I then changed

this.draw();

to

_this.draw();

and it worked.

though the

this.clear();

and the this.update() are still the same, they never seemed to give errors in the first place.

Can anyone explain why this is? and maybe point me to a better solution?
thanks in advance.

update

Here's what it should be:

var Game = function () {
var _this = this;

this.initialize = function () {
    if (canvas.isSupported()) {
        sprites[0] = new Player();

        this.update();
    }
}

this.update = function () {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
}

this.draw = function () {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }


    setTimeout(function () { _this.update(); }, 10);
}

this.clear = function () {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩起发的微风 2024-10-30 13:42:25

当您这样做时:

setTimeout(this.update, 10);

确实正确地将对“更新”函数的引用传递给系统,但是当浏览器稍后实际调用该函数时,它将不知道this 应该是。您可以执行以下操作:

var me = this;
setTimeout(function() { me.update(); }, 10);

这将确保在调用“update”时,将使用正确设置的 this 作为对对象的引用来调用它。

与其他一些语言不同,函数最初被定义为对象的属性,这一事实并不本质上将该函数绑定到该对象。同样,如果您有一个具有属性的对象,那么它就是一个简单的数字:

   maxLength: 25,

那么值“25”不会与该对象有任何特别的关系;这只是一个值。在 JavaScript 中,函数也只是值。因此,程序员有责任确保每当以某种“特殊”方式调用函数时将 this 设置为适当的值。

When you do this:

setTimeout(this.update, 10);

that does correctly pass the reference to your "update" function to the system, but when the browser actually calls the function later, it will have no idea what this is supposed to be. What you can do instead is the following:

var me = this;
setTimeout(function() { me.update(); }, 10);

That will ensure that when "update" is called, it will be called with this set correctly as a reference to your object.

Unlike some other languages, the fact that a function is defined initially as a property of an object does not intrinsically bind the function to that object. In the same way that if you had an object with a propertly that's a simple number:

   maxLength: 25,

well the value "25" won't have anything in particular to do with the object; it's just a value. In JavaScript, functions are just values too. Thus it's incumbent upon the programmer to make sure that this will be set to something appropriate whenever a function is called in some "special" way.

離人涙 2024-10-30 13:42:25

您的问题是您使用对象文字而不是实例化对象

尝试这样做:

var Game = function() {
  this.initialize = function () {
    if (canvas.isSupported()) {
      sprites[0] = new Player();
      this.update();
    }
  };
  this.update = function() {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
  };

  this.draw = function() {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }

    setTimeout(this.update, 10);
  };

  this.clear = function() {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
  };
}

现在使用:

 var myGame = new Game();

You problem is that you use an object literal instead of an instantiated object

Try to do it this way instead:

var Game = function() {
  this.initialize = function () {
    if (canvas.isSupported()) {
      sprites[0] = new Player();
      this.update();
    }
  };
  this.update = function() {
    for (var i = 0; i < sprites.length; i++) {
        sprites[i].update();
    }

    this.draw();
  };

  this.draw = function() {
    this.clear();

    for (var i = 0; i < sprites.length; i++) {
        sprites[i].draw();
    }

    setTimeout(this.update, 10);
  };

  this.clear = function() {
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height);
  };
}

now use:

 var myGame = new Game();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文