javascript javascript对象,自引用问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5339634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 16:52:42  来源:igfitidea点击:

javascript object, self reference problem

javascriptoopmethods

提问by Restart

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

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

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 objectwhere 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.

但是调用 Game.update() 会给出未定义 draw 方法的错误。我找不到真正的解决方案。最终我发现了这个How to call a method inside a javascript object答案似乎是我需要保护 this 引用,例如: var _this = this;但我无法在文字符号中使用它,所以我将代码更改为对象构造函数(我想这就是它的名字)并添加了变量。

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.

并且 this.update() 仍然相同,它们似乎从一开始就没有给出错误。

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);
}

}

}

回答by Pointy

When you do this:

当你这样做时:

setTimeout(this.update, 10);

that doescorrectly 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 thisis supposed to be. What you can do instead is the following:

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

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

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

这将确保当“更新”被调用时,它将被this正确地设置为对您的对象的引用。

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 thiswill be set to something appropriate whenever a function is called in some "special" way.

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

回答by Martin Jespersen

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();