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 is the watered down version of a function I am using elsewhere to run animations sequentially.
Expected behavior:
this.foothree
is processed by the interval adding foo to the interval. this.foo
is then processed adding footoo
to the interval which is finally processed alerting "bar".
Problem:
when this.foothree
is processed, an error is thrown:
TypeError: this.add_work is not a function.
Why don't I use something simpler:
Basically I need a function which allows me to compose a more complex animation made of simpler animations to the queue to be processed so I can reuse that animation. Foothree
in this instance is just simulating a call which would add the real animation, footoo
, to the queue to be processed. Footoo
would be composed of simpler animations, foo
, which would be executed sequentially.
this
returns the [[ThisValue]]
property of the EnvironmentRecord
of the LexicalEnvironment
of the ExecutionContext
of the running function (see the spec).
Its value depends on how the function is called. If you call
this.foo = function(){
function footoo(){alert("bar");}
this.add_work(footoo);
};
in the function being declared there is no add_work
method.
You should adopt var _self = this;
pattern in order to point the correct calling context.
Basically the code should be rewritten as follows:
function main(){
var _self = this;
this.work = [];
this.start_working = function() {
try{
if(_self.work.length > 0){
var y = _self.work.shift();
y.func(y.args);
}
}
catch(e){alert(e)};
};
this.add_work = function(f, a){
_self.work.push({func:f, args:a});
};
this.foo = function(){
function footoo(){alert("bar");}
_self.add_work(footoo);
};
this.foothree = function(){
_self.add_work(_self.foo);
};
this.start = function(){
setInterval(function(){_self.start_working();}, 1);
};
};
Edit:
removed .bind(this)
from original code.