The volume "this" inside the object

This (below) ended up giving the error "maximum call stack size". It is like the "this" method is interpreted inside the this.actions object. Inside this object, does this refer to this object or instance of the Unit class? If the first, placing the .bind (this) object at the end of this.actions object, make "this" instead refers to an instance of the class? 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 } 
+5
source share
4 answers

The this in the actions object will refer to the actions object.

Some possible fixes may look like this:

 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 call these methods, you can use call or apply

eg:

 var coolUnit = new Unit(); Unit.actions.moveUp.call(coolUnit); 

Understanding this in the context of objects requires some work, but here are some resources:

How does the keyword "his" work?

http://unschooled.org/2012/03/understanding-javascript-this/

http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/

TL DR - There are a number of mental β€œrules” that you can use to keep track of what this is in a given context. For instance. The "left point" rule, where the object to the left of the "point" gets 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() has a set of this bindings that points to an action object because it is to the left of the point.

Or you can use call / bind / apply to bind this to the context you want, as shown above.

+2
source

Use bind

Cause:

allows you to:

var r = new Unit ();

When u call r.actions.moveup (), the 'this' passed in the moveup function is an action.

 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 } 
+2
source

Another solution: this not a variable. A nested function has access to all the variables defined in the "parent" function (clousure) - you can create a variable, assign it this and use it instead of this , and it will do what you want and expect:

 function Unit(){ var self = this; self.move = function(direction){ switch(direction){ case 'up': { console.log('foo'); break; } case 'down': { console.log('foooo'); break; } } console.log('bar'); } self.shoot = function(){console.log('zap')} self.actions = { 'moveUp' : function(){ self.move('up') }, 'moveDown' : function(){ self.move('down') }, 'shoot' : function(){ self.shoot() } } return self } 
+1
source

I recently looked at this article about this.

In section 4.2, it uses an example similar to your code and emphasizes the trap of forgetting the β€œnew”. 'this' in a function call points to a global object (window or browser), so when you return it, you put your functions in a global object and then return a link to it. If you used the new Unit () and did not return it, you would get an object with your functions on it.

You can use bind, but I think it will be something like Unit.bind (Unit), which will look weird.

You can also use the factory function to return an object, and you don’t have to worry about forgetting a new one

 function Unit(){ var move = function(direction){ switch(direction){ case 'up': { console.log('foo'); break; } case 'down': { console.log('foooo'); break; } } console.log('bar'); }; var shoot = function(){console.log('zap')}; var actions = { moveUp : function(){ move('up') }, moveDown : function(){ move('down') }, shoot : shoot }; return { actions:actions }; } var player1=Unit(); player1.actions.shoot(); player1.actions.moveDown(); player1.actions.moveUp(); 

I removed this from the call to move, part of the problem is actions, this is an object, not a function, therefore, although you can use the binding to functions inside the object, you can, just like me in the code, just close above the functions and then set his.

Also, if you use self = this and do not use the new keyword, you still have a link to the window / browser object and create a global scope.

0
source

All Articles