this keyword in arrow function
Arrow functions have a lexical this
which means that the value of this
inside the function is the same as the value of this
outside the function.
It does not mean that this
points to an object containing all the variables from outside the function.
const anObject = {
aValue: "example value",
aMethod: function() {
console.log("aMethod", this.aValue);
const arrow = () => {
console.log("arrow", this.aValue);
}
arrow();
}
}
anObject.aMethod();
const copyOfAMethod = anObject.aMethod;
copyOfAMethod();
The this keyword not working with arrow functions
There's not really enough context to give you a good answer, but one thing stands out. Arrow functions maintain scope, so this
inside function click()
and const click
may well be different. In the ES6 version, this
will refer to whatever was this
during the closure creation, which may not be what you want.
Arrow Functions at MDN clears it up:
An arrow function does not have its own
this.
…Which means that this
will be inherited from the declaring scope.
ES6 arrow functions aren't just a new way of declaring functions, and there's nothing inherently wrong with function myFunction(...)
syntax, nor is it going away. Arrow functions avoid some verbosity when passing a function as an argument (e.g. to forEach
) and avoid the need to rebind a function to a different this
in some cases. Converting all function declarations to arrow syntax is not an upgrade.
Arrow Functions and This
Short answer: this
points at the nearest bound this
- in the code provided this
is found in the enclosing scope.
Longer answer: Arrow functions
do not have this
, arguments
or other special names bound at all - when the object is being created the name this
is found in the enclosing scope, not the person
object. You can see this more clearly by moving the declaration:
var person = {
name: "Jason"
};
person.shout = () => console.log("Hi, my name is", this);
And even more clear when translated into a vague approximation of the arrow syntax in ES5:
var person = {
name: "Jason"
};
var shout = function() {
console.log("Hi, my name is", this.name);
}.bind(this);
person.shout = shout;
In both cases, this
(for the shout function) points to the same scope as person
is defined in, not the new scope that the function is attached to when it is added to the person
object.
You cannot make arrow functions work that way, but, as @kamituel points out in his answer, you can take advantage of the shorter method declaration pattern in ES6 to get similar space savings:
var person = {
name: "Jason",
// ES6 "method" declaration - leave off the ":" and the "function"
shout() {
console.log("Hi, my name is", this.name);
}
};
Fat arrow or function() with this keyword
Use the traditional function declaration, because it will decouple your handleUpdate()
function from the UI, so:
- you can implement it in a totally different file and reuse it wherever you need its functionality
- the function does not need to have an
input
variable defined in the context where it's used
If you're still doubting that's the way to go, VueJS also uses traditional functions in several places, having stuff that's actually not working if fat arrow functions were used:
From Vue's official docs:
Don’t use arrow functions on an options property or callback, such as
created: () => console.log(this.a)
[...]. Since arrow functions are bound to the parent context,this
will not be the Vue instance as you’d expect, often resulting in errors such asUncaught TypeError: Cannot read property of undefined
.
So yeah, don't worry about using traditional functions, especially if you can explain the why's behind your choice.
Related Topics
JavaScript: Client-Side Vs. Server-Side Validation
How to Add Two Strings as If They Were Numbers
Calculate Age Given the Birth Date in the Format Yyyymmdd
Updating Address Bar With New Url Without Hash or Reloading the Page
How to Force Js to Do Math Instead of Putting Two Strings Together
Remove Empty Elements from an Array in JavaScript
What Does [Object Object] Mean
When Are You Supposed to Use Escape Instead of Encodeuri/Encodeuricomponent
Fastest Way to Flatten/Un-Flatten Nested JavaScript Objects
What Are Valid Date Time Strings in JavaScript
What Is the "Right" Json Date Format
How to Get the Browser Viewport Dimensions
How to Add a Class to a Given Element
Access Java/Servlet/Jsp/Jstl/El Variables in JavaScript
JavaScript Check If Variable Exists (Is Defined/Initialized)
Why Is the Method Executed Immediately When I Use Settimeout