嗨我试图让我的脑袋围绕javascript oop并遇到问题,我正在构建一个构造函数类,在类我定义属性现在我想定义一些方法来改变那些属性,但是当我instanciate对象并调用方法,consol告诉我属性是未定义的。我想这可能与范围有关,我一直在寻找谷歌很多,但所有介绍性文章基本相同。
这是一个简化版本的代码。在我的示例代码中,我希望一个形状在画布上移动。它自己的对象将拥有控制其移动的方法(现在正好)。当我实例化对象时,我调用它的moveRight方法,该方法应该改变它的xy坐标。然后每一秒我都会在一个单独的函数中将它渲染到屏幕上,该函数调用对象x和y属性
//这里我定义了对象
function Mechanoid(){
//object properties
this.life=100;
this.x=500;
this.y=200;
this.anArray=new Array(0, 0); //can i create an array like this? i know it works when called from outside the object
//object methods
this.moveAround=function(){
var clock=setInterval(Function () {
this.x=this.x+1; //console log says undefined
this.y=this.y+1;
this.anArray[0]=this.x; //console says cannot read propety of null
this.anArray[1]=this.y;
},1000);
}
}
//then instanciate
var mech=new Mechanoid;
mech.moveAround(); // calls method to change object properties
//A request for the x any y coordinates of mech object will be called in a render function where it
//will be drawn to the canvas.
有人能告诉我为什么无法从对象方法中访问这些属性吗?以及我必须做什么才能访问它们?谢谢...语法中可能缺少一个括号或我在运行中写的东西我不认为原始代码中的语法错误,我不认为这就是问题。
答案 0 :(得分:1)
当您使用window.setInterval
时,setInterval
是window.setInterval
的简写,您需要维护对象的引用。
执行回调函数时,this
不会引用setInterval
来自的window.setInterval
来电。 window
在不同的上下文中调用您的回调函数,即var self = this;
的上下文。
一种解决方案是使用this
。虽然self
的值根据上下文而变化,但this.moveAround = function () {
var self = this;
var clock = setInterval(function () {
self.x = self.x + 1;
self.y = self.y + 1;
self.anArray[0] = self.x;
self.anArray[1] = self.y;
}, 1000);
}
是一个任意变量,它维护对您分配给它的任何对象的引用。
function
此外,您需要将“功能”中的“F”更改为小写f(Function
,而不是Function.prototype.bind
)。
修改强>
您还可以在ES5环境中使用this
。它返回一个函数,该函数将moveAround
设置为一个对象(在本例中为调用this.moveAround = function () {
setInterval(function () {
this.x = this.x + 1;
this.y = this.y + 1;
this.anArray[0] = this.x;
this.anArray[1] = this.y;
}.bind(this));
}
的对象)。
this
JavaScript的window.setInterval
被传闻称为“破碎”。 {{1}}是出现混淆的主要示例。始终要注意“this-functions”执行的上下文。
答案 1 :(得分:0)
您在this
函数中丢失了上下文(setInterval
)。试试:
this.moveAround=function(){
var that = this;
var clock=setInterval(function () {
that.x=that.x+1;
that.y=that.y+1;
that.anArray[0]=that.x;
that.anArray[1]=that.y;
},1000);
}
}
答案 2 :(得分:0)
这完全是关于scope
。
function Mechanoid() {
var self = this; // cache this
// bla bla
this.moveAround = function() {
var clock = setInterval(function () {
self.x = self.x + 1; // no longer undefined
self.y = self.y + 1;
// continue this way
}
}
}
答案 3 :(得分:0)
内部setInterval
处理程序this
是指window
。你需要使用闭包:
this.moveAround=function(){
var self = this;
var clock=setInterval(function () {
self.x=self.x+1; //console log says undefined
self.y=self.y+1;
self.anArray[0]=self.x; //console says cannot read propety of null
self.anArray[1]=self.y;
}, 1000);
}
}
或bind
要运行的上下文:
this.moveAround=function(){
var clock=setInterval(function () {
this.x=this.x+1; //console log says undefined
this.y=this.y+1;
this.anArray[0]=this.x; //console says cannot read propety of null
this.anArray[1]=this.y;
}.bind(this), 1000);
}
}
答案 4 :(得分:0)
您有两个错误:
this
(其他解决方案向您展示如何使用上面一级var that = this;
处理它)F
编写了函数 - 更改为小写!