This (below) ended up giving me a "maximum call stack size exceeded" error. It seems like it's due to the way "this" is being interpreted within the "this.actions" object. Within that object, does "this" refer to that object, or the instance of the Unit class? If the former, would putting a .bind(this) on the end of the "this.actions" object make "this" refer to the class instance instead? If so, why? If not, why not?
function Unit(){
this.move = function(direction){
switch(direction){
case 'up': { console.log('foo'); break; }
case 'down': { console.log('foooo'); break; }
}
console.log('bar');
}
this.shoot = function(){console.log('zap')}
this.actions = {
'moveUp' : function(){ this.move('up') },
'moveDown' : function(){ this.move('down') },
'shoot' : function(){ this.shoot() }
}
return this
}
The keyword this
in the actions
object will refer to the actions
object.
Some possible fixes might look like:
function Unit(){
var self = this;
this.move = function(direction){
switch(direction){
case 'up': { console.log('foo'); break; }
case 'down': { console.log('foooo'); break; }
}
console.log('bar');
}
this.shoot = function(){console.log('zap')}
this.actions = {
'moveUp' : function(){ this.move('up') }.bind(self),
'moveDown' : function(){ this.move('down') }.bind(self),
'shoot' : function(){ this.shoot() }.bind(self)
}
return this
}
Or, when you invoke those methods, you could use call
or apply
eg:
var coolUnit = new Unit();
Unit.actions.moveUp.call(coolUnit);
Understanding this
in the context of objects takes some work but here are some resources:
How does the "this" keyword work?
http://unschooled.org/2012/03/understanding-javascript-this/
http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/
TL;DR - There are series of mental "rules" you can use to help keep track of what this
is in a given context. Eg. The left-of-the-dot rule where the object to the left of the "dot" gets the this
binding.
Object.foo() <- `this` in the method `foo` will point to `Object`
Using the "rule" mentioned above, you can rationalize that new Unit.actions.moveUp()
would have the this
binding set to point to the actions object because its left-of-the-dot.
Or you can use call
/bind
/apply
to bind the this
to the context you wish as shown above.
Use bind
Reason:
lets say:
var r = new Unit();
When u call r.actions.moveup() , 'this' passed in the moveup function is actions.
function Unit(){
this.move = function(direction){
switch(direction){
case 'up': { console.log('foo'); break; }
case 'down': { console.log('foooo'); break; }
}
console.log('bar');
}
this.shoot = function(){console.log('zap')}
this.actions = {
'moveUp' : function(){ this.move('up') }.bind(this),
'moveDown' : function(){ this.move('down') }.bind(this),
'shoot' : function(){ this.shoot() }.bind(this)
}
return this
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With