Arrow Syntax VS ES5 function scope [duplicate] - javascript

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
...
}

Related

How to call a arrow function using addEventlistenr before initializing the arrow function? [duplicate]

This question already has answers here:
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 6 months ago.
if I use arrow function instead of normal function flip and do add addeventlistiner to it before initializing the arrow function then I am not able to call the function.
**
Not Working
console.log(cards);
cards.forEach((card) =>
card.addEventListener("click",flip));
var flip = ()=>{
console.log("card flipped");
}
output : on clicking of the card it should give me the output as "card flipped",
but it does not do anything.
Working
var flip = ()=>{
console.log("card flipped"); }
const cards = document.querySelectorAll(".card");
console.log(cards);
cards.forEach((card) =>
card.addEventListener("click",flip));
output : on clicking of the card it is giving me the output as "card flipped",
How do I call the arrow function before initializing it ?
You can't call an expression function before the definition.
However, if you wanted to use a declared function instead of an arrow function with the 'function' tag, you could arrange your code in the way you described.
Example:
function flip() {
console.log('card flipped)
}
Similar question:
why-can-i-use-a-function-before-its-defined-in-javascript

javascript function within an object is undefined [duplicate]

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 4 years ago.
const md = {
methodOne: () => {
console.log(this.anotherMethod())
},
anotherMethod: () => 'anotherMethod'
}
When I do md.methodOne() I got anotherMethod is undefined error. How do I call anotherMethod in methodOne?
The problem is in your arrow functions.
An arrow function does not have its own this; the this value of the enclosing lexical context is used i.e. Arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope they end up finding this from its enclosing scope . Thus, in the following code, the this within the function that is passed to setInterval has the same value as this in the lexically enclosing function:
Also,
you don't need to type return when you have :
() => return 'some message'
The arrow function will return implicitly the value or the result of an expression:
const msg = () => 'some message'
const result = () => 5 * 5; //25
Just for the sake of it, this is how it should look:
const md = {
methodOne:function () {
console.log(this.anotherMethod());
},
anotherMethod: function (){
return 'anotherMethod';
}
}
console.log(md.methodOne());

Arrow function in Javascript Object [duplicate]

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.

Visibility of "this" in Arrow Functions [duplicate]

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 values for arrow functions [duplicate]

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
}

Categories