The Mastering the Arcane Art of JavaScript-mancy series are my humble attempt at bringing my love for JavaScript to all other C# developers that haven’t yet discovered how awesome this language and its whole ecosystem are. These articles are excerpts of the super duper awesome JavaScript-Mancy book a compendium of all things JavaScript for C# developers.

It is time to continue upgrading your JavaScript-Fu to the next level of mastery! This time I present to you ES6 arrow functions , a way to bring the beauty of C# lambda expressions to JavaScript.

The Arrow Function

Hi! You can experiment with all the examples in this article directly within this jsBin .

Arrow functions are a great feature in ES6 that feel very much like C# lambda expressions. They give you a beautiful and terse syntax that let’s you write:

The above example of arrow function has an implicit return statement that returns the expression to the right of the fat arrow => . This simple notation is only valid if the body of your arrow function has a single statement.

Like in C# you’ll often see arrow functions used in conjunction with array methods such as filter (the JavaScript version of LINQ ’s Where ):

An arrow function can also return an object via the object initializer syntax. When returning a new object like this, you’ll need to wrap it inside parenthesis (so that the JavaScript runtime understands that it is indeed an object and not a block of code):

Arrow functions provide a terser syntax that function expressions but as functions themselves they are a little bit special, and when I say a little I mean a lot :

They don’t have this They don’t have an arguments object You cannot use bind , apply and call to set the context in which they are evaluated You cannot use new nor super

Indeed if you look at the ECMA-262 spec:

14.2.16 Arrow Functions – Runtime Semantics: Evaluation

An ArrowFunction does not define local bindings for arguments , super , this , or new.target . Any reference to arguments , super , this , or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function.

Read more within the spec at http://bit.ly/es6-spec

But what does it mean for arrow functions to not have their own version of this nor arguments ?

Well it means that when you refer to this or arguments within an arrow function you are actually referring to this or arguments in the enclosing environment. Let’s clarify this with an example.

Let’s say that we have gollum that wants to be pleasant before he stabs you in the back and steals your wedding ring. If we use normal functions to define his greetings:

// call it in the context of the gollum objectgollum.saysHi();// => Hi! I am Gollum! Gollum!!!!// => "[object Window] stabs you in the back and steals your wedding ring while saying 'My Preciouuuuuus'"/ => Hi! I am Gollum! Gollum!!!!

As we expected gollum happily salutes us and after a while stabs us in the back. The only problem being that it is gollum no longer but the Window object. Nothing new. We learned about this strange behavior in Mastering the Arcane Art of JavaScript-mancy for C# Developers – Chapter 1: The Many a One JavaScript Quirks . But what happens if we use an arrow function instead of a normal function?

The arrow function guarantees that the right version of this is used. What is happening? Because the arrow function doesn’t have its own version of this it accesses the this defined by the saysHi method (effectively behaving like a closure). Because saysHi was called using the dot notation gollumWithArrowFunctions.saysHi then the object itself is the value of this and thus eveything works and we die an ignominious death at Gollum’s hands.

What are the consequences of this? You may be asking yourself. Well, the most exciting consequence of an arrow function not having its own this is that it makes them more resistant to the problems with this that you saw in The Many A One JavaScript Quirks

Let’s bring this concept home using yet another example, the same one we used in The Many A One JavaScript Quirks :

Again, if you substitute the anonymous function expression for an arrow function you solve the problem! And in a much elegant way than binding the function explicitly (with bind ) or by using a closure ( var self = this ):

Now that we’ve learned about the good parts of the arrow function and how it can help us write terser code and avoid some problems with the this keyword let’s take a look at its darker sides: when an arrow function doesn’t behave like a function.

ECMA-262 Function.prototype.bind and Arrow Functions

If Target is an arrow function or a bound function then the thisArg passed to this method will not be used by subsequent calls to the function

You cannot use bind with arrow functions . If you try to bind an arrow function to an object it won’t work. Let’s illustrate this with an example:

In this example we have saruman , another epic javascriptmancer, with a couple of methods. One raiseUrukhai is a regular function, the other telekineticStaffAttack uses an arrow function . If we call these methods using the dot notation:

saruman.raiseUrukhai();// => Saruman, the White raises a Urukhai from the pits of Isengardsaruman.telekineticStaffAttack();// => [object Window] uses his staff to throw you across the room /"telekinetically/" speaking// this would be undefined instead of Window if we used strict mode

If you look at the output of the telekineticStaffAttack method you may be confused to see the Window object as this instead of saruman himself. You have to remember that arrow functions have no this and so, when you use this inside an arrow function, you refer to this in the enclosing environment. In this case, because the arrow function is defined within an object in turn defined within the global scope, the closer this is the Window object (or undefined in case of strict mode). Again, the rules we learned about this in The Many a One JavaScript Quirks don’t apply to arrow functions and calling an arrow function using the dot notation doesn’t evaluate the arrow function in the context of the object.

If we try to use bind to bind these two methods to a different object:

// if we try to bind these two methods to a new objectlet boromir = {name: 'Boromir of Gondor', toString(){return this.name;}};let raiseUrukhaiBound = saruman.raiseUrukhai.bind(boromir);raiseUrukhaiBound();// => Boromir of Gondor raises a Urukhai from the pits of Isengard

We can appreciate how we can bind a normal function but when we try to bind an arrow function :

In this example I am using a constructor function and the new keyword to instantiate a fiery warg. We haven’t seen any of those concepts yet since I am reserving it for the OOP section of the series. They are still the best way to exemplify the similar behavior of arrow functions and bound functions so I hope you’ll forgive me. Essentially you use the new keyword to instantiate new objects via constructor functions . When you apply the new keyword on any function the JavaScript runtime instantiates an object {} , sets it as the this value of the function, then evaluates the function and finally returns it. This is useful because it is the this value that the wark method is going to enclose and safeguard for the rest of the program execution.

After creating willyTheWarg we got ourselves an arrow function wark and a bound function jump . If we execute any of them we will be able to appreciate how this refers to the warg itself:

// this is an arrow functionwillyTheWarg.wark();// => willy, the litte warg warks!: Wark! Wark!// and this is the bound functionwillyTheWarg.jump();// => willy jumps around

This is the expected behavior, but what happens if we are mean and take these functions away from willyTheWarg ?

Well the bound function , as we learned inJavaScript Quirks, will still have willyTheWarg as its context:

This similar behavior and the fact that neither bound nor arrow functions can be bound (re-bound in the case of the bound function) makes both types of function practically identical in this context. The only different being that bound functions don’t need a closure, you can just bind a normal function to whatever object you want by just calling the bind method. Arrow functions on the other hand can be seen to be implicitly bound to their enclosing context by virtue of the closure.

If func is an arrow function or a bound function then the thisArg will be ignored by the function [[Call]] in step 6.

If func is an arrow function or a bound function then the thisArg will be ignored by the function [[Apply]] in step 5.

In addition to bind , you cannot use call nor apply on an arrow function to change its context . If you rememberJavaScript Quirks, you can use call and apply to explicitly set the context in which a function is executed, that is, the value of this :

In the example above you can easily appreciate how instead of scary caragor the ${this} within the wark arrow function is evaluated as willy, the little . This demostrates how arrow functions ignore the context when called with either call or apply .

Another interesting feature of arrow functions is that they don’t have arguments object. What does that mean? Just like with this if you attempt to access the arguments object within an arrow function you’ll access the arguments of the enclosing environment.

If you remember More Useful Function Patterns – Multiple Arguments every function in JavaScript has a arguments object that you can use to access which arguments where passed to a function. So if you have a normal function that logs the arguments object:

So as you can see in both these examples, arrow functions don’t have their own arguments object and use the arguments object of their enclosing environment. But What if we want to send an arbitrary number or arguments to an arrow function? Well in that case you should use the rest operator :

In summary, whenever you use arguments inside an arrow function you’ll be accessing the enclosing environment’s arguments object. So if you want to send multiple arbitrary arguments to an arrow function use the rest operator .

Arrow Functions and the New and Super Operators

The new and super operators are two operators that we will see in depth in the OOP section of the series. The new operator lets you create new instances of objects when applied to a any function which will act as a constructor. The super keyword is new in ES6 and lets you access methods in parent objects within an inheritance chain.

In much the same way as with bind , call and apply , you cannot use new nor super with an arrow function .

Concluding

In this article you learned about arrow functions which resemble lambdas in C#. Arrow functions let you use a terser syntax than the normal function syntax and help you avoid problems with the this keyword by using the this value of their enclosing environment.

Arrow functions are a little bit special in what regards to this since they are the only functions in JavaScript that don’t have their own this value. Because of this characteristic you cannot use bind , call or apply to specify the context in which an arrow function will be evaluated. In a similar fashion you cannot use the new and super operators with an arrow function .

Additionally, arrow functions don’t have their own arguments object, if you try to access arguments inside an arrow function you’ll access the arguments object within the enclosing function. This means that if you want for an arrow function to take an arbitrary number of arguments you’ll need to use the rest syntax .

Buy the Book!

Are you a C# Developer interested in learning JavaScript?Then take a look at the JavaScript-mancy book , a complete compendium of JavaScript for C# developers.