This question already has answers here:
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 5 years ago.
let objNewWay = {
width:400,
height:300,
area: () => this.width*this.height
};
console.log(objNewWay.area()); // NaN
let objOldWay = {
width:400,
height:300,
area: function() {
return this.width*this.height;
}
};
console.log(objOldWay.area()); // 120000
I don't understand why the arrow function in Javascript object does not seems to work. If you look at the code above, the first console.log prints NaN, and the second prints the number as expected.
https://jsbin.com/pazazikayi/edit?js,console
From the documentation :
An arrow function expression has a shorter syntax than a function
expression and does not bind 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.
You have to use the old way like you already showed
area: function() {
return this.width*this.height;
}
if you still want to use the arrow function, you have to call the object itself
let objNewWay = {
width:400,
height:300,
area: ()=> objNewWay.width*objNewWay.height
};
console.log(objNewWay.area()); // NaN
The arrow functions are not lambdas, and the way you use it will refer to a different scope from your object's.
For instance, from the console:
let theObj = {
whereAmI: () => console.log(this)
}
theObj.whereAmI();
// Window...
If you want to use this keyword, use to the area: function(){} way.
Related
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
What does "this" refer to in arrow functions in ES6?
(10 answers)
Closed 1 year ago.
I'm new to javascript and having trouble understanding the difference between arrow function and normal function when including this keyword, here is the example I read from MDN:
var obj = { // does not create a new scope
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}
obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}
In this example arrow function b() can not access i attribute in the object because it references the window
var obj = {
count : 10,
doSomethingLater : function(){ // of course, arrow functions are not suited for methods
setTimeout( () => { // since the arrow function was created within the "obj", it assumes the object's "this"
this.count++;
console.log(this.count);
}, 300);
}
}
obj.doSomethingLater(); //log 11 on the console
However, in the second example, code within the arrow function can access the count attribute. Both functions are defined within the object but only the second function can access the object's attribute, could someone give me some hints why is that? Thanks in advance!
This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 5 years ago.
I was trying to experiment with some JavaScript code. I am not sure why the ES6 syntax fails.
String.prototype.spacify = function() {
console.log(this.split('').join(' '));
}
'hello world'.spacify();
^^ This works GREAT!
But, When I do this
String.prototype.spacify = () => {
console.log(this.split('').join(' '));
}
'hello world'.spacify();
When I convert the function to Arrow function, I get this.split is not defined. I didn't understand. Is arrow syntax doing something special with scoping?
Please enlighten!
In arrow function the context of this refers to the outer this. Here the this of the function test is equal to the this in the arrow function.
arrow function doesn't create it's own context, it just takes the outer context
function test() {
String.prototype.spacify = () => {
console.log(this.split('').join(' '));
}
}
In arrow functions, the scope does not change.
Meaning:
const globalThis = this;
String.prototype.spacify = () => {
// this === globalThis
...
}
This question already has answers here:
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 6 years ago.
I have two cases
const test = {
foo: function (){
this.bar();
},
bar: function (){
console.log('bar');
}
}
test.foo();
in this case, everything works correctly.
const test = {
foo: () => {
this.bar();
},
bar: () => {
console.log('bar');
}
}
test.foo();
In second case I get error:
Uncaught TypeError: Cannot read property 'bar' of undefined
I know I can wrote test.bar() in foo function, but I'm interested why this not available in arrow functions scope in this case.
Normally, the value of this in a function depends on how that function is called.
Arrow functions import the value of this from the scope in which the function was created.
In the middle of an object literal, the value of this will depend on what is around the object literal, but certainly won't be the object itself.
This question already has answers here:
What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript?
(14 answers)
Closed 6 years ago.
I'm reading through the annotated source for the Parsley javascript library, and I keep seeing notations that I don't fully understand. Google searches aren't really helping as google is ignoring "() =>" or "=>" as useful search terms.
Here's an example:
if (event) {
this.submitEvent = $.extend({}, event, {preventDefault: () => {
ParsleyUtils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
this.validationResult = false;
}});
}
I can guess what is happening, but I don't understand the syntax or the name of the function / lambda declaration or pattern.
What is the name of the pattern or style of function declaration? What is its purpose?
These are referred to as arrow functions, which are basically an ES6 approach to leverage functions in a slightly new way. For some simple background on whats going on, MDN explains the idea as such
Two factors influenced the introduction of arrow functions: shorter functions and lexical this.
Check out this example...
var self = this;
setInterval(function growUp() {
// The callback refers to the `self` variable of which
// the value is the expected object.
self.age++;
}, 1000);
with arrow syntax becomes
// `this` here is the same as `this` in the setInterval
setInterval(() => {
this.age++; // `this` properly refers to this in the outer scope
}, 1000);
So with your example, the "traditional" representation could be as such...
var self = this;
if (event) {
self.submitEvent = $.extend({}, event, { preventDefault: function() {
// [...]
self.validationResult = false;
}});
}
Another great use of arrow functions is for one liners
[1,2,3,4].map(num => num * 2); // [2,4,6,8]
This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 5 years ago.
I am trying to understand arrow functions in ECMAScript 6.
This is the definition I came across while reading:
Arrow functions have implicit this binding, which means that the
value of the this value inside of an arrow function is aways the
same as the value of this in the scope in which the arrow function
is defined!
According to the definition, I believe this for an arrow function should contain the same block level values that the arrow function was defined in.
Code:
var test = {
id: "123123",
k: {
laptop: "ramen",
testfunc: () => console.log(this)
}
}
console.log(test.k.testfunc);
However, I am getting this result from the code
function testfunc() {
return console.log(undefined);
}
What I thought I would get would be an output of:
{"laptop": "ramen"}
if I ran this
console.log(test.k.testfunc());
Let's transform into the equivalent ES5 code:
var test = {
id: "123123",
k: {
laptop: "ramen",
testfunc: function(){return console.log(this)}.bind(this)
}
}
Remember that this depends on how you call the function. The outer this isn't inside a function, so it will default to undefined in strict mode.
Simplified scenario below:
console.log(this) // undefined
var test = {
a: this // same `this` as above
}
You are defining the arrow function in the same scope that you defined var test. If you are defining test in the global scope, then the arrow function's context will be the global scope too.
If you are defining test inside of a method, the arrow function will share the method's context.
function method() {
const self = this;
const test = {
foo: () => console.log(self === this);
}
test.foo()
// console: true
}