Arrow functions V.S. Functions
7466 ワード
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
As so often: it depends. Arrow functions have different behavior than function declarations/expressions, so let's have a look at the differences first:
Arrow functions don't have their own
Inside
Inside
Inside
Inside
In the function expression case,
This makes arrow functions useful if you need to access the
If you are not very familiar with MDN - this YDKJS = this & Obeject prototypes
ES2015 distinguishes between functions that are callable and functions that are constructable. If a function is constructable, it can be called with
Functions created through function declarations/expressions are both constructable and callable.
Arrow functions (and methods) are only callable.
If you are trying to call a non-callable function or to construct a non-constructable function, you will get a runtime error.
Knowing this, we can state the following.
Replaceable:
Functions that don't use
Functions that are used with
Constructor functions
Function/methods added to a prototype (because they usually use
Variadic functions (if they use
Generator functions, which require the
Lets have a closer look at this using your examples:
This won't work because arrow functions cannot be called with
Most likely not, because prototype methods usually use
Similarly for methods in an object literal. If the method wants to reference the object itself via
It depends. You should definitely replace it if you are aliasing the outer
Since arrow functions don't have their own arguments, you cannot simply replace them with an arrow function. However, ES2015 introduces an alternative to using arguments: the rest parameter . When should I use arrow functions in ECMAScript 6? Do ES6 arrow functions have their own arguments or not? What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind? How to use arrow functions (public class fields) as class methods?
=> above is a response from this stack overflow question <=
Questions
AssignmentExpression v.s. PrimaryExpression ?
lexical
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
console.logInside
createObject
: 21Inside
bar
: 42// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
console.logInside
createObject
: 21Inside
bar
: 21In the function expression case,
this
refers to the object that was created inside the createObject
. In the arrow function case, this
refers to this
of createObject
itself.This makes arrow functions useful if you need to access the
this
of the current environment:// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Note that this also means that is not possible to set an arrow function's this
with .bind
or .call
.If you are not very familiar with
this
, consider reading2. Arrow functions cannot be called with new
ES2015 distinguishes between functions that are callable and functions that are constructable. If a function is constructable, it can be called with
new
, i.e. new User()
. If a function is callable, it can be called without new
(i.e. normal function call).Functions created through function declarations/expressions are both constructable and callable.
Arrow functions (and methods) are only callable.
class
constructors are only constructable.If you are trying to call a non-callable function or to construct a non-constructable function, you will get a runtime error.
Knowing this, we can state the following.
Replaceable:
Functions that don't use
this
or arguments
.Functions that are used with
.bind(this)
Not replaceable:Constructor functions
Function/methods added to a prototype (because they usually use
this
)Variadic functions (if they use
arguments
(see below))Generator functions, which require the
function*
notationLets have a closer look at this using your examples:
Constructor function
This won't work because arrow functions cannot be called with
new
. Keep using a function declaration/expression or use class
.Prototype methods
Most likely not, because prototype methods usually use
this
to access the instance. If they don't use this
, then you can replace it. However, if you primarily care for concise syntax, use class
with its concise method syntax:class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Object methods
Similarly for methods in an object literal. If the method wants to reference the object itself via
this
, keep using function expressions, or use the new method syntax:const obj = {
getName() {
// ...
},
};
Callbacks
It depends. You should definitely replace it if you are aliasing the outer
this
or are using .bind(this)
:// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
But: If the code which calls the callback explicitly sets this
to a specific value, as is often the case with event handlers, especially with jQuery, and the callback uses this
(or arguments
), you cannot use an arrow function!Variadic functions
Since arrow functions don't have their own arguments, you cannot simply replace them with an arrow function. However, ES2015 introduces an alternative to using arguments: the rest parameter .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Related question:Questions
AssignmentExpression v.s. PrimaryExpression ?
lexical
this
also affects super
and that they have no .prototype
Reference
この問題について(Arrow functions V.S. Functions), 我々は、より多くの情報をここで見つけました https://velog.io/@galbimandu/Arrow-functions-V.S.-Functionsテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol