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]
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 2 years ago.
I am sure that I misunderstand how i can access function properties from one of its prototypes .
i may got -10 because of this question , but I truly need help in understanding why it always returns undefined
here is a reference
function lookup() {
if (!(this instanceof lookup)) {
return new lookup();
}
this.url = "/administration/lookups";
};
lookup.prototype.partial_create = () => {
alert(this.url);
};
var lookup1 = function(){
this.url = "/administration/lookups";
}
lookup1.prototype.makealert = ()=>{
alert(this.url);
}
$(()=>{
new lookup().partial_create();
new lookup1().makealert();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
It's because you've defined both the prototype methods as arrow functions - which behave differently from other functions with regard to the this keyword. (This indeed is the main point of using arrow functions in the first place - but they are misplaced here.) In particular (as you can read at the above link), arrow functions use the this of their enclosing scope - which here is the global scope. So this does not refer to your instance of lookup, but to the global object - hence this.url is just the global variable url, which (since you haven't defined such a variable) is undefined.
To show the difference, run the below snippet - which is identical to yours with the arrow functions replaced by "regular" function declarations. This now works as you presumably intend:
function lookup() {
if (!(this instanceof lookup)) {
return new lookup();
}
this.url = "/administration/lookups";
};
lookup.prototype.partial_create = function() {
alert(this.url);
};
var lookup1 = function(){
this.url = "/administration/lookups";
}
lookup1.prototype.makealert = function() {
alert(this.url);
}
$(()=>{
new lookup().partial_create();
new lookup1().makealert();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
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.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
Normally I'd assign an alternative "self" reference when referring to "this" within setInterval. Is it possible to accomplish something similar within the context of a prototype method? The following code errors.
function Foo() {}
Foo.prototype = {
bar: function () {
this.baz();
},
baz: function () {
this.draw();
requestAnimFrame(this.baz);
}
};
Unlike in a language like Python, a Javascript method forgets it is a method after you extract it and pass it somewhere else. You can either
Wrap the method call inside an anonymous function
This way, accessing the baz property and calling it happen at the same time, which is necessary for the this to be set correctly inside the method call.
You will need to save the this from the outer function in a helper variable, since the inner function will refer to a different this object.
var that = this;
setInterval(function(){
return that.baz();
}, 1000);
Wrap the method call inside a fat arrow function
In Javascript implementations that implement the arrow functions feature, it is possible to write the above solution in a more concise manner by using the fat arrow syntax:
setInterval( () => this.baz(), 1000 );
Fat arrow anonymous functions preserve the this from the surrounding function so there is no need to use the var that = this trick. To see if you can use this feature, consult a compatibility table like this one.
Use a binding function
A final alternative is to use a function such as Function.prototype.bind or an equivalent from your favorite Javascript library.
setInterval( this.baz.bind(this), 1000 );
//dojo toolkit example:
setInterval( dojo.hitch(this, 'baz'), 100);
i made a proxy class :)
function callback_proxy(obj, obj_method_name)
{
instance_id = callback_proxy.instance_id++;
callback_proxy.instances[instance_id] = obj;
return eval('fn = function() { callback_proxy.instances['+instance_id+'].'+obj_method_name+'(); }');
}
callback_proxy.instance_id = 0;
callback_proxy.instances = new Array();
function Timer(left_time)
{
this.left_time = left_time; //second
this.timer_id;
this.update = function()
{
this.left_time -= 1;
if( this.left_time<=0 )
{
alert('fin!');
clearInterval(this.timer_id);
return;
}
}
this.timer_id = setInterval(callback_proxy(this, 'update'), 1000);
}
new Timer(10);
This question already has answers here:
Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
(4 answers)
Closed 6 years ago.
Right now in my helper is using function()
updateCVId: function() {
return this._id; //return the real id
}
It's working, but if I use ()=>
updateCVId:()=> {
return this._id; //return undefined
}
then this._id is undefined.
The same is for the events:
'click .foo': function(evt, tmp) {
console.log(this._id); //log the real id
}
and
'click .foo': (evt, tmp)=> {
console.log(this._id); //log undefined
}
Can someone tell me if I use ()=> , how to get the data?
Thank you guys.
Arrow functions => are designed to automatically bind the context this from lexical scope. In your situation this is undefined, because it runs in 'strict mode'.
To solve your problem you can:
1) Use a regular function, as you did already:
var actions = {
//...
updateCVId: function() {
return this._id; //return the real id
}
//...
};
2) Use an ES6 shorthand function notation:
var actions = {
//...
updateCVId() {
return this._id; //return the real id
}
//...
};
The difference between function() {} and => is in the this context and how the invocation affects this.
In function() {} this is determined by the way function is invoked. If invoking it as a method on the object, this will be the object itself: actions.updateCVId().
I call it soft linked this.
In an arrow function case => this is automatically bound to this of the lexical scope where the function is defined. In your example it's an undefined, which is default case for 'strict mode'.
No matter how the arrow function is invoked later, it will have this as undefined.
I call it hard linked this.
You can find more details about this keyword in this article.