我第一次面对JavaScript中的OOP以及随之而来的所有麻烦......
我有这个函数/ Object / class /具有方法mainLoop()
的任何应该显示一些下降文本的东西 - 就像在电影 The Matrix 中一样。当我调用它时虽然我得到了未定义的变量错误并使用调试器,但我发现mainLoop()
this
内部指的是Window
而不是调用该方法的对象。
以下是代码:
function Matrix(config) {
return {
//[...lots of other vars...],
drops: [],
lines: [],
//final string to put in the container
str: "",
mainLoop: function(){
var tmp = "";
//randomly create a "character drop"
//(not if there's already a drop)
for(var i = 0; i < this.cols; i++){
if(this.drops[i] == 0 && Math.random() < this.freq){
this.drops[i] = irandom(this.rows) + 1;//new drop
tmp += randomChar();//output drop
}
else tmp += lines[0].charAt(i);
}
this.lines[0] = tmp; // <-------------- ERROR
//update already created drops
tmp = "";
for(var j = 0; j < this.cols; j++){
if(this.drops[j] > 0){
tmp += this.randomChar();
this.drops[j]--;
}
else tmp += " ";
}
this.lines[this.rowIndex] = tmp;
this.rowIndex = (this.rowIndex+1) % this.rows;
//render the entire text
this.str = "";
for(var l in this.lines)
this.str += l + "<br/>";
$(container).html = this.str;
},
start: function(){
for(var i = 0; i < this.cols; i++)
this.drops[i] = 0;
timer = setInterval(this.mainLoop ,this.delay);
},
stop: function(){
clearInterval(this.timer);
},
randomChar: function(){
return this.chars.charAt(irandom(this.chars.length));
},
irandom: function(x){
return Math.floor(Math.random()*x);
}
}
};
然后我将此函数称为:
var config = {
container: "#container",
rows: 20,
cols: 20,
delay: 2000
};
var m = Matrix(config);
m.start();
浏览器控制台说:
TypeError: this.lines is undefined
(代码注释显示错误的确切点)。此外,调试器说,此时,this
指向Window
,而不是m
正如我所期望的那样...我的推理有什么问题?提前感谢您的帮助。
答案 0 :(得分:2)
更改start
功能:
start: function(){
var self = this;
for(var i = 0; i < this.cols; i++)
this.drops[i] = 0;
timer = setInterval(function() {
self.mainLoop();
}, this.delay);
}
this
指向window
,因为范围已发生变化。
答案 1 :(得分:1)
由于JavaScript是基于原型的,可能(如果你还没有)尝试按照这个模型进行:
function Matrix(config) {
this.property = config.firstmember;
this.property2 = config.secondmember;
return function() { console.log('hello world') };
}
Matrix.prototype = {
someMethod: function() {
//do something
},
start: function() {
//console.log('hello world');
},
stop: function() {
//do something
}
}
var config = {
firstMember: 'foo',
secondMember: 'bar'
}
var m = new Matrix(config);
//console output: "hello world"
/*var m = {
property: 'foo',
property2: 'bar',
____proto___: Matrix: {
someMethod: function() {
//do something
},
start: function() {
//console.log('hello world');
},
stop: function() {
//do something
}
}
}*/
另请参阅有关setInterval的the answer to this question。
setInterval回调函数是Window对象的成员;因此,'this'指的是窗口。您需要将当前对象的参数传递给setInterval内的回调。有关详细信息,请参阅上面的链接。
答案 2 :(得分:0)
如果您需要对调用对象的引用,我建议将其作为参数传递给函数。