Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?

It seems to me that, in ES6, the following two functions are very nearly identical:

function () {   return this; }.bind(this);  () => {   return this; }; 

The end result seems the same: arrow functions produce a JavaScript function object with their this context bound to the same value as the this where they are created.

Obviously, in the general sense, Function.prototype.bind is more flexible than arrow functions: it can bind to values other than the local this, and it can bind any function's this at any point in time, potentially long after it is initially created. However, I'm not asking how bind itself is different from arrow functions, I'm asking how arrow functions differ from immediately calling bind with this.

Are there any differences between the two constructs in ES6?

like image 207
Alexis King Avatar asked Sep 12 '15 04:09

Alexis King


People also ask

What is the difference between a normal function and an ES6 arrow function?

Since regular functions are constructible, they can be called using the new keyword. However, the arrow functions are only callable and not constructible, i.e arrow functions can never be used as constructor functions. Hence, they can never be invoked with the new keyword.

What is the use of arrow functions What is the difference between normal function and arrow functions?

Unlike regular functions, arrow functions do not have their own this . Arguments objects are not available in arrow functions, but are available in regular functions. Regular functions created using function declarations or expressions are 'constructible' and 'callable'.

What is an ES6 arrow function?

Arrow function is one of the features introduced in the ES6 version of JavaScript. It allows you to create functions in a cleaner way compared to regular functions. For example, This function // function expression let x = function(x, y) { return x * y; }

What is the main functional advantage of arrow functions in JavaScript versions following ES6?

There are two major benefits of using Arrow functions. One is that it's a shorter syntax and thus requires less code. The main benefit is that it removes the several pain points associated with the this operator.


2 Answers

There are no (significant) differences.

Well, okay, that's a little premature. There are three tiny differences unique to arrow functions.

  1. Arrow functions cannot be used with new.

    This means, of course, that they do not have a prototype property and cannot be used to create an object with the classically-inspired syntax.

    new (() => {}) // TypeError: () => {} is not a constructor 

    This is probably for the best, though—the way new works would not make much sense with bound functions.

  2. Arrow functions do not have access to the special arguments object that ordinary JavaScript functions have access to.

    (() => arguments)(1, 2, 3) // ReferenceError: arguments is not defined 

    This one is probably a little bit more of a gotcha. Presumably this is to remove one of JavaScript's other oddities. The arguments object is its own special beast, and it has strange behavior, so it's not surprising that it was tossed.

    Instead, ES6 has splats that can accomplish the same thing without any magic hidden variables:

    ((...args) => args)(1, 2, 3) // [1, 2, 3] 
  3. Arrow functions do not have their own new.target property, they use the new.target of their enclosing function, if it exists.

    This is consistent with the other changes to remove "magically" introduced values for arrow functions. This particular change is especially obvious, considering arrow functions can't be used with new anyway, as mentioned above.

Otherwise, arrows are just like bound functions, semantically. It's possible for arrows to be more performant, since they don't have to carry around the extra baggage and since they don't need to be converted from ordinary functions first, but they're behaviorally exactly the same.

like image 161
Alexis King Avatar answered Sep 18 '22 05:09

Alexis King


There are a few differences:

  • Arrow functions cannot be constructed. While both arrow functions and bound functions both don't have a .prototype property, the former do throw an exception when called with new while the latter just ignore the bound value and call their target function as a constructor (with the partially applied bound arguments, though) on the new instance.

    function F() {} var f = () => {},     boundF = F.bind({}); console.log(new boundF(), new boundF instanceof F) // {}, true console.log(new f) // TypeError 
  • Arrow functions do have lexical arguments, new.target and super as well (not only lexical this). A call to an arrow function does not initialise any of those, they are just inherited from the function the arrow function was defined in. In a bound function, they just refer to the respective values of the target function.

  • Arrow functions don't actually bind a this value. Rather, they don't have one, and when you use this it is looked up like a variable name in the lexical scope. This does allow you to lazily define an arrow function while this is not yet available:

    class X extends Object {     constructor() {          var f = () => this, // works              boundF = function(){ return this; }.bind(this); //                                                    ^^^^ ReferenceError          super(); // initialises `this`          console.log(f(), f() == this); // {}, true     } } new X; 
  • Arrow functions cannot be generator functions (though they can return generators). You can use .bind() on a generator function, yet there is no way to express this using an arrow function.

like image 23
Bergi Avatar answered Sep 19 '22 05:09

Bergi