Where is my 'this'? Using the object method as a callback function

I have a general question about the javascript specification or the implementation of the function pointer (delegates?), Which are the points for the methods of the object.

Please read the following code snippet. Here we have an object with the 'this' method to access the field of the object. When we call this method as usual ( o.method(); ), the value of the specified field of the object is returned. But when we create a pointer to this method (callback) and call it, the value is undefined, since the scope of 'this' is now a global object.

 var o = { field : 'value', method : function() { return this.field; } }; o.method(); // returns 'value' var callback = o.method; callback(); // returns 'undefined' cause 'this' is global object 

So where is my 'this'?

+6
javascript pointers oop callback
source share
3 answers

"this" is late binding. that is, it is attached to the thing immediately before the function is executed. How you call your function depends on it.

if you call it (invokation function):

  myfunction(); 

"this" is bound to a global object

if you call it (invokation method):

  myobject.myfunction(); 

"this" binds to "myobject"

you can also call it (invokation call):

  myfunction.call(myobject); 

in this case "this" is attached to myobject

exists also (constructor call):

  new MyFunction(); 

in which "this" is bound to a newly created empty object, the prototype of which is MyFunction.prototype.

This is how javascript creators talk about it. (and I think this is discussed in the spec) Various ways of calling a function.

The new version of the ecmascript standard (ecmascript5) includes a prototype library "bind" method, which returns a new function with "this" prebound to what you specify. eg:

  mynewfunction = myfunction.bind(myobject); mynewfunction(); 

the call to mynewfunction has "this" already associated with myobject.

+10
source share

You can specify this context, for example, when calling a method using .apply() or .call() methods. In your case, as you said, the context has changed. If you really need to make field be o.field , you must explicitly state this, for example, using closure when defining your method method .

+1
source share

You are right, this is invalid javascript. I was thinking about using a new function that allows you to have multiple instances:

 function o2(value) { var _this = this; this.field = value; this.method = function() { return _this.field; }; } 

var test1 = new o2('blah'); var test2 = new o2('meh');

var callback1 = test1.method; var callback2 = test2.method;

alert(callback1()); alert(callback2());

Alternatively, if you want to continue using the singlet, you can reference o from the object.

 var o = { field : 'value', method : function() { return o.field; } }; 
-one
source share

All Articles