Lexical this simply means that this is looked up in lexical scope.
The value of this in an arrow function is inherited from the enclosing (lexical) scope. Functions have a special variable this that refers to the object via which the method was invoked. As the value of this is dynamically given based on the function invocation, it is sometimes called dynamic this .
Lexical scoping (sometimes known as static scoping ) is a convention used with many programming languages that sets the scope (range of functionality) of a variable so that it may only be called (referenced) from within the block of code in which it is defined. The scope is determined when the code is compiled.
Lexical scope means that in a nested group of functions, the inner functions have access to the variables and other resources of their parent scope. This means that the child's functions are lexically bound to the execution context of their parents. Lexical scope is sometimes also referred to as static scope.
You seem to have the correct understanding of what happens with this
in an arrow function. I will offer an explanation that I think adds to the conversation and hopefully solidifies your understanding.
As you probably know, when you define a function and use a variable inside of it, it checks if the variable has been defined in its scope. If it is, it uses it! If not, it checks the enclosing scope for that variable definition. It keeps checking enclosing scopes until it finds the variable or reaches global scope. Now, function definitions that are not arrow functions define this
for you, implicitly. Thus, they will never check an enclosing scope when you try to use this
in their scope (because they find it in their own scope!). Arrow functions do NOT define their own this
, so they go to the enclosing scope and look for it just as they would with any variable you try to use in their scope.
As a way to describe the behavior of this
in arrow functions, the term "lexical this
" is somewhere between confusing and wrong.
The behavior is quite simply is that this
in an arrow function refers to the this
in the surrounding function--or perhaps it would be simpler and more accurate to just say that the arrow function does not define (or "bind") its own this
.
The unfortunately terminology of "lexical this
" may have been perpetuated by a poor choice of wording in the MDN article on arrow functions (which until recently also encouraged people to use the obsolete term "fat arrow function"). This has now been cleaned up. Note also that the spec never uses the term "lexical" in relation to this
in arrow functions. I'd be curious to know who came up with this expression.
Lets say you have a click listener. In that listener you are performing some AJAX operation like setTimeout
. After the set time has been reached, the code inside the callback will be executed. Inside that callback you may have accessed this
to change the color of the clicked button. But the control will be out of context due to AJAX operation. ES2015 introduced the arrow function to fix that problem. The arrow function captures the this
value of the enclosing context.
The example use-case is:
$('.btn').click(function () {
setTimeout(function () {
$(this).text('new');
// This will cause an error since function() defines this as the global object.
} ,100);
});
To avoid this case:
$('.btn').click(function () { // <- Enclosing context
setTimeout( () => {
$(this).text('new') }
// This works, because this will be set to a value captured from the enclosing context.
,100);
});
I wrote an article about this, the gist of which is: do not think about what "lexical this" means. Do not worry about what "this" means within an arrow function. You already know (or at least, if you don't, it's the fault of your own confusion about some outer functional scope, and not the fault of the arrow function).
You may have been conditioned over the years to get anxious about what "this" would end up meaning when you needed to use it within some nested or higher-order function. But with arrow functions, you just can STOP worrying about it. You almost certainly already know what "this" refers to in the context that you're currently in: BUT... within the arrow function, it hasn't changed. So you can think of arrow functions as the simple case, and function(){} as the more complex one.
Do you write some function and start an if(){} block and worry about what "this" could have changed to inside it? No? Same with arrow functions. That's what "lexical this" means. It means "Hakuna matata."
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