I have a constructor that registers an event handler:
function MyConstructor(data, transport) { this.data = data; transport.on('data', function () { alert(this.data); }); } // Mock transport object var transport = { on: function(event, callback) { setTimeout(callback, 1000); } }; // called as var obj = new MyConstructor('foo', transport);
However, I cannot access the data
property of the object created within the callback. It looks like this
does not refer to the created object, but to another object.
I also tried using object methods instead of anonymous functions:
function MyConstructor(data, transport) { this.data = data; transport.on('data', this.alert); } MyConstructor.prototype.alert = function() { alert(this.name); };
But it also has the same problem.
How to access the correct object?
The following are several ways to access the parent context in the child context - H2>- You can use
- Store a reference to context/this in another variable (see example below).
- Use ES6 arrow functionality.
- Change code, functional design and architecture - for this you should master Design Patterns a> in JavaScript.
to bind the a>()
function.1.Use
bind()
functionIf you are using Underscore.js - http://underscorejs.org/#bind
2. Store a reference to context/this in another variable
3.Arrow function
About
What you should know about this
this
(aka "context") is a special keyword within each function whose value depends only on how the function is called, not how/when/what Where it is called it is defined. It is not affected by lexical scope like other variables (except arrow functions, see below). Here are some examples:To learn more about
this
, please view the MDN documentation .How to quote the correct
this
Use arrow functions
ECMAScript 6 introduces arrow functions, which can be thought of as lambda functions. They do not have their own
this
binding. Instead,this
is looked up in scope just like a normal variable. This means you don't have to call.bind
. This isn't their only special behavior, see the MDN documentation for more information.Don’t use
this
You don't actually want to access
this
specifically, but access the object it refers to. That's why a simple solution is to simply create a new variable that also references the object. Variables can have any name, but common ones areself
andthat
.Since
self
is a normal variable, it follows lexical scoping rules and can be accessed inside the callback. This also has the advantage that you can access thethis
value of the callback itself.Explicitly setting the callback's
this
- Part 1It may seem like you have no control over the value of
this
since its value is set automatically, but that's not actually the case.Every function has method
.bind
[docs], which returns a new function wherethis
Bind to a value. This function has exactly the same behavior as the function you call.bind
, except thatthis
is set by you. No matter when or how the function is called,this
will always refer to the passed value.