Arrow vs classic method in ES6 class
The feature you are using is not part of ES6. It's the class fields proposal. It allows you to initialize instance properties without having to write a constructor. I.e. your code:
class MyClass {
myMethod = () => {
this.myVariable++;
}
}
is exactly the same asclass MyClass {
constructor() {
this.myMethod = () => {
this.myVariable++;
};
}
}
And this also shows you what the difference is between a normal class method an a method created via a class field:- A normal method is shared between all instances of the class (it is defined on the prototype)
- A "class field method" is created per instance
- Use "class field methods" if you need a method per instance. Such is the case for event handlers that need to access the current instance. Access to
this
also only works if you are using an arrow function. - Use normal class methods in all other cases.
ES6 functions, arrow functions and 'this' in an ES6 class
It's important to know that this syntax:
class A {
method = () => {}
}
is just syntactic sugar for creating an instance method in the class constructor:class A {
constructor() {
this.method = () => {}
}
}
Note: This syntax is not an official part of the JavaScript language yet (currently in stage 3) so you must use a transpiler like Babel to handle it.The value of this
within method
is the class A
because that is what this
points to in the constructor (since arrow functions inherit the context from the scope they are defined in):
class A { constructor() { this.method = () => this; }}
const instance = new A();console.log(instance.method() === instance); // true
Are arrow functions faster (more performant, lighter) than ordinary standalone function declaration in v8?
V8 developer here. Arrow functions are (mostly) just "syntactic sugar" for conventional function declarations. There is no performance difference.
Methods in ES6 objects: using arrow functions
Arrow functions are not designed to be used in every situation merely as a shorter version of old-fashioned functions. They are not intended to replace function syntax using the function
keyword. The most common use case for arrow functions is as short "lambdas" which do not redefine this
, often used when passing a function as a callback to some function.
Arrow functions cannot be used to write object methods because, as you have found, since arrow functions close over the this
of the lexically enclosing context, the this
within the arrow is the one that was current where you defined the object. Which is to say:
// Whatever `this` is here...
var chopper = {
owner: 'Zed',
getOwner: () => {
return this.owner; // ...is what `this` is here.
}
};
In your case, wanting to write a method on an object, you should simply use traditional function
syntax, or the method syntax introduced in ES6:var chopper = {
owner: 'Zed',
getOwner: function() {
return this.owner;
}
};
// or
var chopper = {
owner: 'Zed',
getOwner() {
return this.owner;
}
};
(There are small differences between them, but they're only important if you use super
in getOwner
, which you aren't, or if you copy getOwner
to another object.)There was some debate on the es6 mailing list about a twist on arrow functions which have similar syntax but with their own this
. However, this proposal was poorly received because that is mere syntax sugar, allowing people to save typing a few characters, and provides no new functionality over existing function syntax. See the topic unbound arrow functions.
What is the difference (if any) between the different function declarations within JavaScript objects?
The "class style function" (shorthand method) is very similar to a regular function. The only difference is that it can't be used as a constructor (i.e. called with new
), and because of that it doesn't have a prototype
property. As for arrow functions, see Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?. In a nutshell, arrow functions don't bind their own this
and arguments
, and can't be used with new
.
In ES6+ there's no reason to use the traditional function syntax in objects, because the shorthand methods syntax is simpler and safer, because if you accidentally try to use a method as a constructor, you'll get an error. As for arrow functions, you can use them only if you don't need to access the object usingIs it down to personal preference? Or do the inner workings change?
this
. Are 'Arrow Functions' and 'Functions' equivalent / interchangeable?
tl;dr: No! Arrow functions and function declarations / expressions are not equivalent and cannot be replaced blindly.
If the function you want to replace does not use this
, arguments
and is not called with new
, then yes.
As so often: it depends. Arrow functions have different behavior than function declarations / expressions, so let's have a look at the differences first:
1. Lexical this
and arguments
Arrow functions don't have their own this
or arguments
binding. Instead, those identifiers are resolved in the lexical scope like any other variable. That means that inside an arrow function, this
and arguments
refer to the values of this
and arguments
in the environment the arrow function is defined in (i.e. "outside" the arrow function):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
Related Topics
How to Get Month and Date of JavaScript in 2 Digit Format
How to Send Images to Node Js with Axios
How to Parseint a String with Leading 0
JavaScript Replace() Method Dollar Signs
Why Does JavaScript Getyear() Return 108
Why Do I Need to Copy an Array to Use a Method on It
Sending Binary Data in JavaScript Over Http
JavaScript String Array to Object
How to Initialize a JavaScript Date to Midnight
Window.Location.Reload with Clear Cache
How to Convert Numbers Between Different Bases in JavaScript
Gmail Extension, Sendmessage to Background from Page Context
Pass Variables to JavaScript in Expressjs
Access Properties of the Parent with a Handlebars 'Each' Loop
How to Execute a Function on Pressing the Enter Key in an <Input> Field