window.onerror = function(e){alert(e)};
function main(){
this.work = [];
this.start_working = function() {
try{
if(this.work.length > 0){
var y = this.work.shift();
y.func(y.args);
}
}
catch(e){alert(e)};
};
this.add_work = function(f, a){
this.work.push({func:f, args:a});
};
this.foo = function(){
function footoo(){alert("bar");}
this.add_work(footoo);
};
this.foothree = function(){
this.add_work(this.foo);
};
this.start = function(){
setInterval(function(){this.start_working();}.bind(this), 1);
};
};
x = new main();
x.start();
x.foothree();
这是我在其他地方用来顺序运行动画的函数的淡化版本。
预期行为:
this.foothree
由间隔添加foo处理。然后处理this.foo
,将footoo
添加到最后处理的区间,警告“bar”。
问题:
处理this.foothree
时,会抛出错误:
TypeError:this.add_work不是函数。
为什么我不使用更简单的东西:
基本上我需要一个函数,它允许我将更复杂的动画组成更简单的动画到要处理的队列,这样我就可以重用那个动画。在这个例子中,Foothree
只是模拟一个调用,它会将真实动画footoo
添加到要处理的队列中。 Footoo
将由更简单的动画foo
组成,它将按顺序执行。
答案 0 :(得分:5)
this
会返回正在运行的函数的[[ThisValue]]
EnvironmentRecord
的{{1}}属性(请参阅the spec)。
它的值取决于how the function is called。如果你打电话
LexicalEnvironment
在声明的函数中没有ExecutionContext
方法。
您应该采用var this.foo = function(){
function footoo(){alert("bar");}
this.add_work(footoo);
};
模式来指出正确的调用上下文。
基本上代码应该按如下方式重写:
add_work
修改强>
从原始代码中删除_self = this;
。
答案 1 :(得分:1)
这个问题有两个组成部分。
首先,它是关于JavaScript中的this
的问题,也就是" target"或"接收器"功能。
JavaScript中函数的目标取决于您是否处于严格模式,函数的调用方式以及是否使用bind
进行绑定。
假设严格模式(您应该始终将'use strict';
放在JavaScript的顶部):
foo(); // this inside foo will be undefined
a.foo(); // this inside foo will be a
a.foo.call(o); // this inside foo will be o
a.foo.apply(o); // this inside foo will be o
a.foo.bind(o)(); // this inside foo will be o
这个问题的第二个方面是作者试图做的事情。我很确定他为链式动画引入的复杂性是不必要的,并且他应该使用requestAnimationFrame
,但是对此的讨论需要另外一个问题。
示例:
function foo() {
document.write('foo', this, '<br/>');
bar();
}
function bar() {
document.write('bar', this, '<br/>');
}
foo();
document.write('------<br/>');
foo.call({});
&#13;