In this lesson, you'll focus on the arrow function, a notable feature introduced in JavaScript's ES6 update. Arrow functions are more than a syntactic novelty; they represent a significant enhancement in writing concise code and offer a streamlined way to handle the this keyword.
You'll learn about their syntax, the benefits they bring, and how they differ from traditional function expressions, especially in their handling of this. By the end of this lesson, you should be comfortable using arrow functions to improve the clarity and efficiency of your JavaScript code.
If you're following along in this beginners course, all you need to know about arrow functions to complete the projects in this course are their syntax. Their handling of this isn't a requirement. However, it's good to be aware of it, as you'll see it in many examples.
How to Write Arrow Function Expressions
Arrow function expressions are similar to regular function expressions you have seen in previous lessons:
// Function Expression
let fToC = function (tempInF) {
return (tempInF - 32) * (5 / 9);
};
// Arrow Function Expression
let fToC = (tempInF) => {
return (tempInF - 32) * (5 / 9);
};
With the syntax options you'll see in the following section, you'll see that you can make this even more concise. This brevity is a great reason to use arrow functions, as it makes your code easier to read and understand. Especially when you're having to nest functions inside of other functions.
Arrow Function Syntax Options
There are a few different ways to write an arrow function that you'll want to be familiar with.
If the function only has exactly one parameter, you don't need any brackets around the parameter definition:
let fToC = tempInF => {
return (tempInF - 32) * (5 / 9);
};
If the function body is only one line long, you don't need the curly braces or the return statement, its implicit, for example:
let fToC = tempInF => (tempInF - 32) * (5 / 9);
let fToC = (tempInF) => (tempInF - 32) * (5 / 9);
If the function has no parameters, you need to include the empty parentheses:
let sayHello = () => console.log("Hello, nomad!");
Likewise, if the function has more than one parameter, you need to include the parentheses:
let add = (a, b) => a + b;
If the function body is more than one line long, you need to include the curly braces and the return statement:
let fToC = (tempInF) => {
let newTemp = (tempInF - 32) * (5 / 9);
return newTemp;
};
How Are Arrow Functions Actually Different?
Arrow functions are not just syntactic sugar. Syntactic sugar is a term used to describe language features that make code easier to read but do not affect the functionality. This is not the case with arrow functions even though they are often used like that. In certain situations, they behave slightly differently from regular function expressions.
In this beginner's course, understanding this distinction isn't necessary. They become more relevant when you delve into more complex structures which are covered in later lessons. That said, it's good to be aware of it!
Arrow functions do not have their own this keyword. Instead, they use the this keyword from the surrounding context.
This means that if you use an arrow function inside of an object, the this keyword will refer to the surrounding context, which is not object itself.
let demo = {
showThis: () => console.log(this),
};
demo.showThis(); // Window { ... }
As you can see, the this keyword inside an arrow function, inside a object literal, refers to the Window object, which is the this in the surrounding context.
If you want to use the this keyword to refer to the object itself, you would need to use a regular function expression:
let demo = {
showThis: function () {
console.log(this);
},
};
demo.showThis(); // {showThis: f}
As you can see, when using this in this example, you get the object itself, which is shown here as an object with just one property, the showThis function.
Example of Leveraging the Arrow Function's this Behavior
There are practical implications due to the behavior of the arrow function in relation to the this keyword. Such as it's practicality when event listeners are involved. Or, more generally, when you start using callbacks and closures a lot.
For instance, take a look at this example:
let demo = {
name: "demo",
sayHello: function () {
console.log(`Hello, ${this.name}!`);
},
sayHelloLater: function () {
setTimeout(() => console.log(`Hello, ${this.name}!`), 1000);
},
};
demo.sayHello(); // Hello, demo!
demo.sayHelloLater(); // Hello, demo! (after 1 second)
Note the combination of function expressions and arrow functions in this example. Let's break the example down step by step:
-
Defining an Object
demo:- An object named
demois created. - This object has a
nameproperty and two methodssayHelloandsayHelloLater.
- An object named
-
Method:
sayHellosayHellois a function expression.- It uses the
thiskeyword to access the current object'snameproperty. thisinsayHellorefers to thedemoobject.
-
Method:
sayHelloLatersayHelloLateris also a function expression.- It uses
setTimeout, which is a higher order function, to delay an operation. - Inside
setTimeout, an arrow function is used as the callback. - The arrow function ensures that
thisinside it still refers to thedemoobject, and so, still has access to thethis.nameproperty.
As you can see, an arrow function can make this type of code much more concise that it would have to be if you were using regular function expressions.
If you were to use a regular function expression in the setTimeout callback, you would need to use the .bind() method to ensure that this refers to the demo object:
let demo = {
name: "demo",
sayHello: function () {
console.log(`Hello, ${this.name}!`);
},
sayHelloLater: function () {
setTimeout(this.sayHello.bind(this), 1000);
},
};
With function expressions, you have to make use of the .bind() method of functions that is used to explicitly set the this keyword to the object provided as an argument.
Arrow Functions and the arguments Object
Regular functions have access to an arguments object. This is an array-like object that contains all of the arguments passed to the function:
function showArgs() {
console.log(arguments);
}
showArgs("Hello", "nomad!");
// Arguments(2) ["Hello", "nomad!", callee: ƒ, Symbol(Symbol.iterator): ƒ]
This can be a handy tool to have access to, especially when you don't know how many arguments will be passed to the function. Function expressions also have an arguments object.
But, arrow functions do not have their own arguments object. Instead, they use the arguments object from the surrounding context, if there is one:
let showArgs = () => console.log(arguments);
showArgs("Hello", "nomad!"); // ReferenceError: arguments is not defined
As you can see, the arguments object isn't present in a regular arrow function.
Summary: What Are Javascript Arrow Functions
You've just completed an lesson on the use of arrow functions in JavaScript, enhancing your understanding of this important ES6 feature. By going through this lesson you've:
- Recognized that arrow functions can provide a more concise syntax for writing functions, which is especially useful when you’re nesting functions.
- Learnt different ways to write arrow functions, such as omitting parentheses and curly braces in certain scenarios.
- Grasped that if the function body has a single expression, braces and the
returnkeyword are optional due to implicit return. - Learned that arrow functions do not have their own
thiscontext, but inherit it from the enclosing execution context, unlike regular functions. - Noted the absence of an
argumentsobject in arrow functions.
Remember, arrow functions not only shorten your code, but they can also simplify the function scope and the behavior of the this keyword, which may be crucial in certain scenarios. Keep practicing to get accustomed to when and how to use them effectively!