JavaScript arrow function: fat arrow syntax, this, return object, tutorial

How arrow functions work in JavaScript: js arrow function, arrow function javascript, javascript fat arrow => syntax, concise vs block body, js arrow function return object with parentheses, lexical this vs methods, no arguments binding, rest parameters, and why arrows are not constructors. Snippets include short expected-output notes from Node runs.

Published

Updated

Read time 4 min read

Reviewed byDeepak Prasad

JavaScript arrow function: fat arrow syntax, this, return object, tutorial

The javascript arrow function syntax (also called a javascript fat arrow or fat arrow function in javascript) uses => between parameters and body. It was standardized in ES2015 and is now the default style for short callbacks. This javascript arrow function tutorial covers concise bodies, when braces and return are required, js arrow function return object parentheses, lexical this, and what arrows cannot do (constructors, own arguments). For the legacy arguments object in normal functions, see JavaScript arguments; for ... in other contexts, see the spread operator in JavaScript.

Tested on: Node.js v20.18.2. A short note after each snippet describes what you should see in the console.


Quick reference

Arrows excel at lexical this and short callbacks; avoid them when you need dynamic this, new, or an arguments binding—use function or class fields instead.

Situation Prefer
Short callback, no own this Arrow
Object method needs this receiver Method shorthand m() { } or function property
Need arguments binding function or (...args) =>
Need new function / class

Block body — general arrow function in javascript

Use a block body when you need statements, local variables, or multiple steps before returning.

javascript
const power = (base, exponent) => {
  let result = 1;
  for (let count = 0; count < exponent; count++) {
    result *= base;
  }
  return result;
};
console.log(power(2, 3));
Output

You should see one line like: 8.


Single parameter — optional parentheses (arrow function js)

With one simple parameter, parentheses are optional:

javascript
let square = (x) => x * x;
console.log(square(3));
Output

You should see one line like: 9.

Same meaning as x => x * x (no parens around x).


Zero or multiple parameters — parentheses required

Use () for zero parameters and (a, b) when there is more than one name (or for non-simple parameter lists).

javascript
const three = () => 3;
let add = (x, y) => x + y;
console.log(three(), add(3, 4));
Output

You should see one line like: 3 7.


Concise body vs block body

Expression body: omit { } and return; the expression is returned.

Block body: use { } and explicit return (unless you intentionally fall through to undefined).

javascript
let addAndMultiply = (x, y) => {
  let sum = x + y;
  let product = x * y;
  return [sum, product];
};
console.log(addAndMultiply(3, 4));
Output

You should see one line like: [ 7, 12 ].


Returning an object literal — js arrow function return object

Braces after => start a block, not an object. Wrap the literal in ():

javascript
const objLit = () => ({ a: 1 });
console.log(objLit());
Output

You should see one line like: { a: 1 }.


Callbacks — javascript arrow function with map

Arrows are a natural fit for Array.prototype.map and similar APIs when you do not need a dynamic this.

javascript
let numbers = [1, 2, 3, 4, 5];
let squares = numbers.map((x) => x * x);
console.log(squares);
Output

You should see one line like: [ 1, 4, 9, 16, 25 ].


Lexical this (strict + forEach)

In strict mode, a classic function passed to forEach gets undefined for this (unless you pass a thisArg). An arrow inherits this from the enclosing call:

javascript
(function () {
  "use strict";
  const greeter = {
    prefix: "Hi ",
    greet(names) {
      names.forEach(function () {
        console.log("classic", this === undefined ? "this:undefined" : this);
      });
    },
  };
  greeter.greet(["a"]);
})();

(function () {
  "use strict";
  const greeter = {
    prefix: "Hi ",
    greet(names) {
      names.forEach((name) => console.log(this.prefix + name));
    },
  };
  greeter.greet(["a", "b"]);
})();
Output

You should see 3 lines: classic this:undefined, then Hi a, then Hi b.

call / apply / bind do not change an arrow’s this:

javascript
const o = {
  x: 2,
  f: function () {
    const arrow = () => this.x;
    return arrow.call({ x: 99 });
  },
};
console.log(o.f());
Output

You should see one line like: 2.


Not a constructor

Using new on an arrow throws because arrows have no [[Construct]] internal method.

javascript
try {
  new (() => {});
} catch (e) {
  console.log(`${e.name}: ${e.message}`);
}
Output

You should see one line like: TypeError: (intermediate value) is not a constructor.


Summary

=> trades features for brevity: no this, arguments, or new—wrap object literals in (), and use method shorthand when the receiver must bind dynamically.

  • => gives compact syntax; expression bodies omit return, block bodies need explicit return.
  • Return object literals with () => ({ ... }) so { is not parsed as a block.
  • Lexical this makes arrows ideal for many callbacks but wrong for prototype methods that need the receiver.
  • Arrows are not constructors and have no own arguments; use function or rest parameters when those matter.

References

MDN documentation for arrow function expressions and dynamic this.


Frequently Asked Questions

1. What is the difference between arrow function javascript and a function declaration?

Arrow functions have a compact syntax, do not bind their own this, arguments, super, or new.target, and cannot be used as constructors. function declarations are hoisted and get a dynamic this when called as a method.

2. How do I js arrow function return object literals?

Wrap the object in parentheses: () => ({ key: 'value' }). Without parens, braces start a block body, not an object literal, so you get undefined or a label parse surprise.

3. Why is this wrong inside my arrow method on an object?

Arrows close over lexical this from where they were created, not the receiver. For methods that need the object (this), use a method shorthand greet() { ... } or a regular function property.

4. Can I use new with an arrow function in javascript?

No. Arrow functions are not constructors and will throw TypeError when used with new.

5. Is there an arguments object in an arrow function?

Arrows do not have their own arguments binding. Use rest parameters (...args) or define a regular inner function if you need the classic arguments object; see also the guide on JavaScript arguments.

6. When must I use parentheses around arrow function parameters?

Use parens when there are zero parameters (), multiple parameters, or non-simple parameters such as defaults, rest, or destructuring. A single simple identifier can omit parens: x => x * x.
Olorunfemi Akinlua

Boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs …