javascript - Arrow function vs function declaration / expressions: Are they equivalent / exchangeable? -


canonical question if find question issues after replacing function declaration / expression arrow function, please close duplicate of one.

arrow functions in es2015 provide more concise syntax. can replace function declarations / expressions arrow functions now? have out for?

examples:

constructor function

function user(name) {   this.name = name; }  // vs  const user = name => {   this.name = name; }; 

prototype methods

user.prototype.getname = function() {   return this.name; };  // vs  user.prototype.getname = () => this.name; 

object (literal) methods

const obj = {   getname: function() {     // ...   } };  // vs  const obj = {   getname: () => {     // ...   } }; 

callbacks

settimeout(function() {   // ... }, 500);  // vs  settimeout(() => {   // ... }, 500); 

variadic functions

function sum() {   let args = [].slice(arguments);   // ... }  // vs const sum = () => {   let args = [].slice(arguments);   // ... }; 

tl;dr: no! arrow functions , function declarations / expressions not equivalent , cannot replaced blindly.
if function want replace not use this, arguments , not called new, yes.


as often: it depends. arrow functions have different behavior function declarations / expressions, lets have @ differences first:

1. lexical this , arguments

arrow functions don't have own this or arguments binding. instead, identifiers resolved in lexical scope other variable. means inside arrow function, this , arguments refer values of this , arguments in environment arrow function defined in (i.e. "outside" arrow function):

// example using 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

// example using 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

in function expression case, this refers object created inside createobject. in arrow function case, this refers this of createobject itself.

this makes arrow functions useful if need access this of current environment:

// common pattern var = this; getdata(function(data) {   that.data = data; });  // better alternative arrow functions getdata(data => {   this.data = data; }); 

note means not possible set arrow function's this .bind or .call.

if not familiar this, consider reading

2. arrow functions cannot called new

es2015 distinguishes between functions callable , functions constructable. if function constructable, can called new, i.e. new user(). if function callable, can called without new (i.e. normal function call).

functions created through function declarations / expressions both constructable , callable.
arrow functions (and methods) callable. class constructors constructable.

if trying call non-callable function or construct non-constructable function, runtime error.


knowing this, can state following.

replaceable:

  • functions don't use this or arguments.
  • functions used .bind(this)

not replaceable:

  • constructor functions
  • function / methods added prototype (because use this)
  • variadic functions (if use arguments (see below))

lets have closer @ using examples:

constructor function

this won't work because arrow functions cannot called new. keep using function declaration / expression or use class.

prototype methods

most not, because prototype methods use this access instance. if don't use this, can replace it. however, if care concise syntax, use class concise method syntax:

class user {   constructor(name) {     this.name = name;   }    getname() {     return this.name;   } } 

object methods

similarly methods in object literal. if method wants reference object via this, keep using function expressions, or use new method syntax:

const obj = {   getname() {     // ...   }, }; 

callbacks

it depends. should replace if you aliasing outer this or using .bind(this):

// old settimeout(function() {   // ... }.bind(this), 500);  // new settimeout(() => {   // ... }, 500); 

but: if code calls callback explicitly sets this specific value, case event handlers, jquery, , callback uses this (or arguments), cannot use arrow function!

variadic functions

since arrow functions don't have own arguments, cannot replace them arrow function. however, es2015 introduces alternative using arguments: rest parameter.

// old function sum() {   let args = [].slice.call(arguments);   // ... }  // new const sum = (...args) => {   // ... }; 

related question:

further resources:


Comments

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -