Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for How and when to use JavaScript arrow functions
LogRocket profile imageMegan Lee
Megan Lee forLogRocket

Posted on • Originally published atblog.logrocket.com

     

How and when to use JavaScript arrow functions

Written byJoe Attardi✏️

The ES2015 standard introduced arrow functions to JavaScript. Arrow functions have a simpler syntax than standard functions, but we’ll also see that there are some important differences in how they behave.

What are JavaScript arrow functions?

Arrow functions can be used almost anywhere a standard function expression can be used, with a few exceptions. They have a compact syntax, and like standard functions, have an argument list, a body, and a possible return value.

We’ll explore arrow functions in detail below, but in general they should be avoided any time you need a newthis binding. Arrow functions don’t have their ownthis; they inherit thethis from the outer scope.

Arrow functions also can’t be used as constructors or generator functions, as they can’t contain ayield statement.

What is the basic syntax of a JavaScript arrow function?

An arrow function consists of a list of arguments, followed by an arrow (made with an equals sign and a greater-than sign (=>), followed by the function body. Here’s a simple example of an arrow function that takes a single argument:

constgreet=name=>{console.log(`Hello,${name}!`);};
Enter fullscreen modeExit fullscreen mode

You can optionally also surround the argument with parentheses:

constgreet=(name)=>{console.log(`Hello,${name}!`);}
Enter fullscreen modeExit fullscreen mode

If an arrow function takes more than one argument, the parentheses are required. Like a standard function, the argument names are separated by commas:

constsum=(a,b)=>{returna+b;}
Enter fullscreen modeExit fullscreen mode

An anonymousarrow function has no name. These are typically passed as callback functions:

button.addEventListener('click',event=>{console.log('You clicked the button!');});
Enter fullscreen modeExit fullscreen mode

If your arrow function body is a single statement, you don’t even need the curly braces:

constgreet=name=>console.log(`Hello,${name}!`);
Enter fullscreen modeExit fullscreen mode

Implicit returns and the JavaScript arrow function

One of the important differences between JavaScript arrow functions and standard functions is the idea of animplicit return: returning a value without using areturn statement.

If you omit the curly braces from an arrow function, the value of the function body’s expression will be returned from the function without needing areturn statement. Let’s revisit thesum function from earlier. This can be rewritten to use an implicit return:

constsum=(a,b)=>a+b;
Enter fullscreen modeExit fullscreen mode

Implicit return is handy when creating callback functions:

constvalues=[1,2,3];constdoubledvalues=values.map(value=>value*2);// [2, 4, 6]
Enter fullscreen modeExit fullscreen mode

Returning an object implicitly

You can return any kind of value you want with an implicit return, but you’ll need a little extra help if you want to return an object. Since an object literal uses curly braces, JavaScript will interpret the curly braces as the function body. Consider this example:

constcreateUser=(name,email)=>{name,email};
Enter fullscreen modeExit fullscreen mode

In this case, there will be no implicit return and the function will actually returnundefined because there is noreturn statement. To return an object implicitly, you need to wrap the object with parentheses:

constcreateUser=(name,email)=>({name,email});
Enter fullscreen modeExit fullscreen mode

Now JavaScript knows this is an implicit return of an object containing thename andemail properties.

Explicit returns and the JavaScript arrow function

Like with standard functions, an arrow function can explicitly return a value with areturn statement:

constcreateUser=(name,email)=>{return{name,email};};
Enter fullscreen modeExit fullscreen mode

How JavaScript arrow functions differ from standard functions

Arrow functions behave differently from standard functions in some other ways.

Nothisbinding

The most significant difference is that, unlike a standard function, an arrow function doesn’t create athis binding of its own. Consider the following example:

constcounter={value:0,increment:()=>{this.value+=1;}};
Enter fullscreen modeExit fullscreen mode

Because theincrement method is an arrow function, thethis value in the function does not refer to thecounter object. Instead, it inherits the outerthis, which in this example would be the global window object.

As you might expect, if you callcounter.increment(), it won’t changecounter.value. Instead,this.value will beundefined sincethis refers to the window.

Sometimes, you can use this to your advantage. There are cases where you do want the outerthis value from within a function. This is a common scenario when using callback functions. Before arrow functions, you’d have to callbind on a function to force it to have a certainthis, or you might have followed a pattern like this:

varself=this;setTimeout(function(){console.log(self.name);},1000);
Enter fullscreen modeExit fullscreen mode

With an arrow function, you get thethis from the enclosing scope:

setTimeout(()=>console.log(this.name));
Enter fullscreen modeExit fullscreen mode

Noarguments object

In a standard function, you can reference thearguments object to get information about the arguments passed to the function call. This is an array-like object that holds all the argument values. In the past, you might have used this to write a variadic function.

Consider thissum function, which supports a variable number of arguments:

functionsum(){lettotal=0;for(leti=0;i<arguments.length;i++){total+=arguments[i];}returntotal;}
Enter fullscreen modeExit fullscreen mode

You can callsum with any number of arguments:

sum(1,2,3)// 6
Enter fullscreen modeExit fullscreen mode

If you implementsum as an arrow function, there won’t be anarguments object. Instead, you’ll need to use the rest parameter syntax:

constsum=(...args)=>{lettotal=0;for(leti=0;i<args.length;i++){total+=args[i];}returnargs;}
Enter fullscreen modeExit fullscreen mode

You can call this version of thesum function the same way:

sum(1,2,3)// 6
Enter fullscreen modeExit fullscreen mode

This syntax isn’t unique to arrow functions, of course. You can use therest parameter syntax with standard functions, too. In my experience withmodern JavaScript, I don’t really see thearguments object being used anymore, so this distinction may be a moot point.

No prototype

Standard JavaScript functions have aprototype property. Before the introduction of theclass syntax, this was the way to create objects withnew:

functionGreeter(){}Greeter.prototype.sayHello=function(name){console.log(`Hello,${name}!`);};newGreeter().sayHello('Joe');// Hello, Joe!
Enter fullscreen modeExit fullscreen mode

If you try this with an arrow function, you’ll get an error. This is because arrow functions don’t have a prototype:

constGreeter=()=>{};Greeter.prototype.sayHello=name=>console.log(`Hello,${name}!`);// TypeError: Cannot set properties of undefined (setting 'sayHello')
Enter fullscreen modeExit fullscreen mode

When to use JavaScript arrow functions vs. standard functions

Arrow functions can be used in a lot of scenarios, but there are some situations where you still need to use a standard function expression. These include:

  • The constructor of a class
  • An object method where you need to access the object via athis value
  • A function that you need to explicitly bind to a giventhis value withFunction.prototype.bind
  • A generator function containingyield statements

Arrow functions particularly shine when used as callback functions, due to their terse syntax. In particular, they are very useful for array methods such asforEach,map, andfilter. Youcan use them as object methods, but only if the method doesn’t try to access the object usingthis. The arrow function is very useful in certain situations. But like most things, arrow functions have potential pitfalls if you don’t use them correctly.

How to define a method using an arrow function

Here’s how you’d define a method using an arrow function:

classPerson{constructor(name){this.name=name;}greet=()=>console.log(`Hello,${this.name}!`);}
Enter fullscreen modeExit fullscreen mode

Unlike a method on an object literal — which as we saw earlier does not get thethis value — here thegreet method gets itsthis value from the enclosingPerson instance. Then, no matter how the method is called, thethis value will always be the instance of the class. Consider this example that uses a standard method withsetTimeout:

classPerson{constructor(name){this.name=name;}greet(){console.log(`Hello,${this.name}!`);}delayedGreet(){setTimeout(this.greet,1000);}}newPerson('Joe').delayedGreet();// Hello, undefined!
Enter fullscreen modeExit fullscreen mode

When thegreet method is called from thesetTimeout call, itsthis value becomes the global window object. Thename property isn’t defined there, so you’ll getHello, undefined! when you call thedelayedGreet method.

If you definegreet as an arrow function instead, it will still have the enclosingthis set to the class instance, even when called fromsetTimeout:

classPerson{constructor(name){this.name=name;}greet=()=>console.log(`Hello,${this.name}!`);delayedGreet(){setTimeout(this.greet,1000);}}newPerson('Joe').delayedGreet();// Hello, Joe!
Enter fullscreen modeExit fullscreen mode

You can’t, however, define the constructor as an arrow function. If you try, you’ll get an error:

classPerson{constructor=name=>{this.name=name;}}// SyntaxError: Classes may not have a field named 'constructor'```{%endraw%}##ConclusionSincethearrivaloftheES2015standard,JavaScriptprogrammershavehadarrowfunctionsintheirtoolbox.Theirmainstrengthistheabbreviatedsyntax;youdontneedthe{%raw%}`function`{%endraw%}keyword,andwithimplicitreturnyoudontneeda{%raw%}`return`{%endraw%}statement.Thelackofa{%raw%}`this`{%endraw%}bindingcancauseconfusion,butisalsohandywhenyouwanttopreservetheenclosing{%raw%}`this`{%endraw%}valuetoanotherfunctionwhenpassedasacallback.Considerthischainofarrayoperations:{%raw%}```javascriptconst numbers = [1, 2, 3, 4]  .map(function(n) {    return n * 3;  })  .filter(function(n) {    return n % 2 === 0;  });
Enter fullscreen modeExit fullscreen mode

This looks fine, but it’s a little verbose. With arrow functions, the syntax is cleaner:

constnumbers=[1,2,3,4].map(n=>n*3).filter(n=>n%2===0);
Enter fullscreen modeExit fullscreen mode

Arrow functions don’t have anarguments object, but they do support rest parameter syntax. This makes it easy to build arrow functions that take a variable number of arguments.

The main advantages of arrow functions are enhanced readability as well as the differentthis behavior, which will make life easier in certain situations where you need to preserve an outerthis value.


LogRocket: Debug JavaScript errors more easily by understanding the context

Debugging code is always a tedious task. But the more you understand your errors, the easier it is to fix them.

LogRocket allows you to understand these errors in new and unique ways. Our frontend monitoring solution tracks user engagement with your JavaScript frontends to give you the ability to see exactly what the user did that led to an error.

LogRocket Signup

LogRocket records console logs, page load times, stack traces, slow network requests/responses with headers + bodies, browser metadata, and custom logs. Understanding the impact of your JavaScript code will never be easier!

Try it for free.

Top comments(2)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
patzi275 profile image
Patrick Zocli
500 bio lost in the database
  • Education
    Institut de Formation et de Recherche en Informatique
  • Joined
• Edited on• Edited

Thanks for sharing

CollapseExpand
 
webjose profile image
José Pablo Ramírez Vargas
  • Location
    Heredia, Costa Rica
  • Work
    Senior software developer @ Intel
  • Joined

Good stuff.

Some comments may only be visible to logged-in visitors.Sign in to view all comments.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Rather than spending hours/days trying to reproduce an elusive bug, you can see the reproduction in seconds with LogRocket.Try it yourself — get in touch today.

More fromLogRocket

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp