为什么'this'在这种情况下不应该是这样
Why is 'this' not what it should be in this context?
我有一个我在画布上使用的函数,我试图清除一个与.animate
函数调用的间隔,但是当我调用.unbind();
时,它仍然未定义日志,当它应该记录超时时,我不知道为什么它不工作,也许你们可以帮助
function Character(model, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {
this.model = model;
this.srcX = srcX;
this.srcY = srcY;
this.srcW = srcW;
this.srcH = srcH;
this.destX = destX;
this.destY = destY;
this.destW = destW;
this.destH = destH;
this.timeout = undefined;
}
Character.prototype = {
draw: function() {
return ctx.drawImage(this.model, this.srcX, this.srcY, this.srcW, this.srcH,
this.destX, this.destY, this.destW, this.destH);
},
animate: function(claymation) {
var top = this; <<<<<--------Set the this variable
var queue = (function() {
var that = this;
var active = false;
if (!this.active) {
(function runQueue(i) {
that.active = true;
var length = claymation.length -1;
>>>>-Set the timeout top.timeout = setTimeout(function() {
claymation[i].action();
if ( i < length ) {
runQueue(i + 1);
if (i === length - 1) {
that.active = false;
}
}
}, claymation[i].time);
})(0);
}
})();
return queue;
},
update: function(callback) {
callback();
},
unbind: function() {
console.log(this.timeout); < Logs undefined
clearTimeout(this.timeout);
console.log(this.timeout); < Also logs undefined?
}
}
更新:我调用unbind on:
player = new Character(playerModel, 0, 130, 100, 100, 150, 150, 100, 100)
if (e.which === 39) {
player.unbind();
key = undefined;
}
完整源代码:https://github.com/Gacnt/FirstGame/blob/master/public/javascripts/superGame.js#L50-L77
您的animate
函数混乱。您已经看到需要将this
引用存储在一个额外的变量(that
, top
,无论什么)中,因为它从调用到调用和从函数到函数变化,但是您没有正确地做到这一点。
var top = this;
var queue = (function() {
var that = this;
var active = false;
if (!this.active) {
// use
that.active = true;
// or
top.timeout = …;
// or
that.active = false;
}
})();
虽然top
是正确的,并且将引用您调用该方法的Character
实例,但that
绝对不是-它将引用全局上下文(window
),这是正常(立即)调用函数(表达式)中的默认this
值。因此,this.active
也很难有一个值,并且您的timeout
属性不会被设置。还要注意,IIFE没有return
任何东西,所以queue
将是undefined
。
相反,您似乎想使用本地active
变量。那就去做吧!您不必使用一些类似Java- this
的关键字来引用"本地"变量—变量只是作用域链中的下一个,因此将使用它。
我不完全确定,但看起来你想要
Character.prototype.animate = function(claymation) {
var that = this; // variable pointing to context
var active = false; // again, simple local variable declaration
if (!active) {
(function runQueue(i) {
active = true; // use the variable
var length = claymation.length -1;
that.timeout = setTimeout(function() { // use property of "outer" context
claymation[i].action();
if ( i < length ) {
runQueue(i + 1);
if (i + 1 === length) {
active = false; // variable, again!
}
}
}, claymation[i].time);
})(0);
}
};
Bergi的意思是:
animate: function(claymation) {
var top = this;
这里你设置top引用this,这是一个实例(我宁愿叫它character,这样你就知道它是character的一个实例)。然后你有一个IIFE,它有自己的执行上下文和一个新值this:
var queue = (function() {
var that = this;
这里that被设置为IIFE的this,它没有被设置,因此将默认为全局/window对象,或者如果处于严格模式,将保持未定义。
var active = false;
if (!this.active) {
这里你得到了窗口。活动,第一次可能未定义,因此测试为真。之后你做:
(function runQueue(i) {
that.active = true;
设置window.active
为true。另外,你正在做:
(function runQueue(i) {
...
})(0);
如果你只是传递一个固定的值,就不需要IIFE,只要在有i
的地方使用0
并删除IIFE,只使用函数体,你不应该在作用域链上需要额外的对象。
最后,两个iife都没有返回任何东西,所以queue仍然是未定义的,所以:
})();
return queue;
返回udefined
的值
- 我想在AngularJS应用程序中创建一个输入数字框,用户不应该在该框上键入十进制数字.(一个整数输入框)
- Javascript代码添加了一些不应该存在的内容
- jQuery:具有class但不具有$(this)的元素
- 有没有任何情况下,一个方法不应该是原型方法
- 当我认为它不应该重新渲染视图时,如何防止 Meteor 在 html 选择 dom 单击事件上重新渲染视图
- Node.js Promise - 代码不应该等到 .then 完成()
- 跳跃运动:旋转轴 – 如果手静止不动,它不应该在 0 左右
- 如果我不应该在组件WillUpdate中调用setState,如何更新状态(使用ReactJS)
- Javascript:尝试从多个没有匹配的数组中采样,在不应该的时候循环递增
- 这个正则表达式不应该工作吗?
- 为什么不应该't我在JavaScript中使用Alert
- 如何避免隐藏不应该隐藏的部分
- 在对javascript/NodeJS应用程序进行原型设计时,应该测试什么,不应该测试什么
- 如果我不应该用流星吗;不需要反应性
- jQuery点击监听器在'It’不应该
- JavaScript排序函数排序时不应该排序
- Javascript插件不应该影响所有的选择框
- jQuery不使用“$(this)”返回必需的元素
- Javascript闭包:这个数组不应该通过getArray进行编辑
- 为什么'this'在这种情况下不应该是这样