Reputation: 166
I'm following along this heroku tutorial and in this section https://devcenter.heroku.com/articles/mean-apps-restful-api#create-the-contact-list-template-and-component there is class listing of ContactListComponent
There's function
private getIndexOfContact = ( contactId : String ) => {
return this.contacts.findIndex( (contact) => { return contact._id === contactId; } );
}
that is used like that:
deleteContact = (contactId: String) => {
var idx = this.getIndexOfContact(contactId);
if (idx !== -1) {
this.contacts.splice(idx, 1);
this.selectContact(null);
}
return this.contacts;
}
Why is the getIndexOfContact implemented like that, instead of ie:
private getIndexOfContact( contactId : String )
{
return this.contacts.findIndex( (contact) => { return contact._id === contactId; } );
}
What is this syntax changing?
Upvotes: 0
Views: 72
Reputation: 164177
They are using an arrow function which handles the context of this
better than a regular function.
Example:
class A {
fn1() {
console.log(this);
}
fn2 = () => {
console.log(this);
}
}
let a = new A();
setTimeout(a.fn1, 10); // Window
setTimeout(a.fn2, 10); // A {}
Another difference between the two is that when using arrow functions as class methods, you don't really get a method but a property on the instance of type function.
That means that the function won't be added to the prototype and won't be added to subclasses.
The compiled js of my example is:
var A = (function () {
function A() {
var _this = this;
this.fn2 = function () {
console.log(_this);
};
}
A.prototype.fn1 = function () {
console.log(this);
};
return A;
}());
As you can see fn1
is assigned to the prototype while fn2
is assigned to the instance in the constructor.
A lot of people will say that using arrow functions as class methods is good practice because it keeps the context of this
for the function, but they are rarely talking about the downsides, so here it is:
class B extends A {
fn1() {
console.log("B.fn1");
super.fn1();
}
fn2 = () => {
console.log("B.fn2");
super.fn2(); // error: Only public and protected methods of the base class are accessible via the 'super' keyword
}
}
There's a way around that of course:
class B extends A {
private oldFn2 = this.fn2;
constructor() {
super();
}
fn1() {
console.log("B.fn1");
super.fn1();
}
fn2 = () => {
console.log("B.fn2");
this.oldFn2();
}
}
But that's way too much work to be able to call super.
Upvotes: 0
Reputation: 342
The syntax changing is a recommended solution to avoid getting issues when using "this" keyword calling per example the declared function as a callback function.
I had a lot of trouble using the "normal" style way, and after using always the solution " = () => { ..." in my projects the problems were gone.
Upvotes: 2