Why this is undefined inside a fat arrow function definition?
Unlike regular functions, Arrow functions does not have a this
of their own, only regular functions and global scope have this
of their own.
Which would mean that whenever this
would be referred in arrow function, it will start looking up the scope to find the value of this
, or in this case, during lookup it found, that the object
is not having a this
of its own, hence, it went up to global scope and bound the value of this
with global scope, where it won't find anything. These two examples will solve your doubt.
var obj = {
a : 'object???',
foo : () => { console.log(this.a) }
};
var a = 'global!!!';
obj.foo(); // global!!!
Wrapping arrow within a functionvar obj = {
a : 'object???',
foo : function() {
return (() => {
console.log(this.a)
})();
}
};
var a = 'global!!!';
obj.foo();
Here, I have tried to explain the behaviour of this
for arrow in depth.https://github.com/anirudh-modi/JS-essentials/blob/master/ES2015/Functions/Arrow%20functions.md#how-this-is-different-for-arrow-functions
This undefined in fat arrow function but is defined in the enclosing scope
You have three different arrow functions and none of them attempts to use this
.
This is a performance optimisation.I actually do not need this in any of the arrow functions, but upon debugging I found that this is undefined in their scope for some reason.
If a variable isn't used in a function then it will not exist in that function, even if it would otherwise be in scope.
This allows, for example:
function foo () {
var bar = something_that_returns_a_memory_intensive_object()
return () => console.log(1);
}
const baz = foo();
After foo
has finished running and returns its function, bar
(and the large object) can be garbage collected.The same is true of this
.
… and when you use it, the variable is closed over and made available.I now added a console log in the arrow function and apparently it is defined!
Why in Fat arrow functions arguments object is undefined
According to MDN
An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.
Why does 'this' return 'undefined' when referred in an arrow function but doesn't when called on an anonymous function?
Because arrow functions don't have their own this
, they close over the this
of the calling context. But non-arrow functions, if they're not bound, take this
based on how they're called. I assume you're calling these functions like this:
obj.getScopeWithArrow();
obj.getScopeWithAnonymous();
In the first case, again, the arrow function doesn't get its own this
so it doesn't matter how you're calling it. In the second case, it does matter, and calling it like that makes this
within the call refer to the same object obj
refers to.Separately: In your example, you must be in strict mode, because
this
can only be undefined
in strict mode.Separately 2: With regard to your method names: this
and "scope" have very, very little to do with one another.
Some examples:
function showThis(label, t) { if (t === window) { console.log(label, "(global object)"); } else { console.log(label, t); }}// Loose mode by default in a non-module script elementlet obj = { arrow: () => { showThis("arrow says ", this); }, normal: function() { showThis("normal says ", this); }};obj.arrow(); // global object (window on browsers)obj.normal(); // obj
function foo() { // Here, we're in strict mode "use strict"; let obj = { arrow: () => { showThis("arrow says ", this); }, normal: function() { showThis("normal says ", this); } }; obj.arrow(); // undefined obj.normal(); // obj
}foo();
Arrow function is undefined when passed as props
Non-arrow functions are still hoisted in classes. If you move bananaEvents after defining the arrow functions your class will work normally.
I tested this just now with
class Test {
vars = { one: this.firstFunction(), two: this.secondFunction() }
firstFunction() { return 1
}
secondFunction = () => 2
}
const test1 = new Test(); // will give an error function undefined
andclass Test2 {
firstFunction() { return 1
}
secondFunction = () => 2
vars = { one: this.firstFunction(), two: this.secondFunction() }
}
const test2 = new Test2(); // works normally
Vue: Access component object inside methods
According to official docs You should use normal function instead of arrow one in order to get access to the component instance :
methods: {
getInput() {
return this.$ref.input.value
}
}
Note that you should not use an arrow function to define a method (e.g.plus: () => this.a++)
. The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect andthis.a
will be undefined.
Why React Function Component's this is undefined
Function components can be written using both arrow functions () => {}
like shown in the above question, or as regular function expressions/declarations such as function Foo() {}
. To understand why the above behavior occurs, it is important to first understand that React components are (often) written within ES6 modules.
Why is this
undefined
in an arrow function component?
One of the properties of modules is that this
at the top "module scope" level is undefined
. This behavior differs from regular scripts:<!-- A "module" is what react component code is usually written in -->
<script type="module">
console.log("Module code (react code) this:", this); // undefined
// ^
const App = () => { // example component |
this // --- taken from surrounding scope ---+
}
</script>
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
From Vue's official docs:
Don’t use arrow functions on an options property or callback, such asSo yeah, don't worry about using traditional functions, especially if you can explain the why's behind your choice.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
.
Related Topics
How to Detect If JavaScript Files Are Loaded
How to Auto-Reload Files in Node.Js
Cross Domain Localstorage with JavaScript
Differencebetween Settimeout(Fn, 0) and Settimeout(Fn, 1)
Add Two Functions to Window.Onload
Jquery Document.Ready VS Phonegap Deviceready
Pass Post Data with Window.Location.Href
How to Pull the File Name from a Url Using JavaScript/Jquery
Why Does If("String") Evaluate "String" as True But If ("String"==True) Does Not
How to Convert a Firestore Date/Timestamp to a Js Date()
Properties of JavaScript Function Objects
Add Commas to a Number in Jquery
Get Width Height of Remote Image from Url
How Do Cors and Access-Control-Allow-Headers Work
External Resource Not Being Loaded by Angularjs
Omitting the Second Expression When Using the If-Else Shorthand