This episode introduces two core concepts of modern JavaScript: concise arrow functions with lexically bound this, and higher-order functions that accept or return other functions. You build habits around callbacks and functional data transformation.

Episode 8 takes you to the heart of modern JavaScript: arrow functions and higher-order functions. Arrow functions introduce a far more concise way to write functions, while also changing how this is handled — and that difference is what confuses people most. Higher-order functions open up the concept that functions can be treated like any other value: passed into other functions and returned from other functions.
These two concepts aren't just a writing style. Higher-order functions are the foundation of the array methods we'll cover in episode 9, the callback patterns in episodes 14 and 16, and almost every modern library. Understanding both now will make the rest of this series much easier.
A key concept to hold from the start: in JavaScript, functions are values. Once you accept that, the rest flows naturally.
Arrow functions are written with =>. When a function only returns a single expression, return and the curly braces can be omitted — this is called an implicit return:
const kaliDua = (angka) => angka * 2;
const sapa = (nama) => `Halo, ${nama}!`;
console.log(kaliDua(21));
console.log(sapa("Arman"));const kaliDua = (angka) => angka * 2 is the concise version of function (angka) { return angka * 2; }. A single parameter may omit parentheses: angka => angka * 2. For single-expression functions, this is the dominant style in modern JavaScript codebases.
When a function contains more than one statement, use a block with an explicit return:
const proses = (nilai) => {
const kuadrat = nilai * nilai;
console.log(`Kuadrat dari ${nilai} adalah ${kuadrat}`);
return kuadrat;
};
console.log(proses(9));const proses = (nilai) => uses curly braces so you're free to write multiple statements. The rule of thumb: no curly braces means implicit return; with curly braces, return must be written explicitly if you want to return a value.
The most fundamental difference between arrow functions and regular functions is the this keyword. Regular functions get this from how the function is called, while arrow functions inherit this from where the function is written — this is called lexical this:
const pengguna = {
nama: "Arman",
perkenalan: function () {
setTimeout(() => {
console.log(`Halo, saya ${this.nama}`);
}, 100);
},
};
pengguna.perkenalan();Inside setTimeout, a regular function would lose the this pointing at pengguna. The arrow function () => instead inherits this from the outer function, so this.nama still reads "Arman". This is the main reason arrow functions are used inside callbacks.
Arrow functions aren't a complete replacement. Don't use an arrow function as an object method when this must point at the object itself:
const mobil = {
merek: "Toyota",
suara: () => {
console.log(`Bunyi dari ${this.merek}`);
},
};
mobil.suara();Because an arrow function's this is lexically bound, this.merek inside suara points at the global scope, not at mobil — the result is Bunyi dari undefined. For methods that need the object's this, use a regular function. We'll dissect the full details of this in episode 12.
A higher-order function is a function that accepts another function as an argument, returns a function, or both. This works because in JavaScript functions are ordinary values that can be stored in variables:
function terapkan(fungsi, nilai) {
return fungsi(nilai);
}
const gandakan = (angka) => angka * 2;
const negatif = (angka) => -angka;
console.log(terapkan(gandakan, 10));
console.log(terapkan(negatif, 10));terapkan(gandakan, 10) sends the gandakan function as an argument and runs it inside. The results are 20 and -10. By separating "what to do" (the function) from "how to run it" (the higher-order function), code becomes much more flexible.
A higher-order function can also produce new functions:
function buatPengali(pengali) {
return (angka) => angka * pengali;
}
const kaliTiga = buatPengali(3);
const kaliLima = buatPengali(5);
console.log(kaliTiga(7));
console.log(kaliLima(7));buatPengali(3) returns a new function that multiplies its argument by 3, and then kaliTiga(7) produces 21. The function factory pattern like this is very common: generating functions already locked onto a particular configuration.
A callback is a function passed to another function to be run later. Combining arrow functions and callbacks produces concise, expressive code:
function prosesDaftar(daftar, transformasi) {
const hasil = [];
for (const item of daftar) {
hasil.push(transformasi(item));
}
return hasil;
}
const harga = [10000, 25000, 40000];
const denganPajak = prosesDaftar(harga, (h) => h * 1.11);
console.log(denganPajak);prosesDaftar(harga, (h) => h * 1.11) sends an arrow function as a callback that adds an 11 percent tax to every price. The result is [11100, 27750, 44400]. Notice that an inline callback makes the transformation flow readable right at the call site.
Callbacks aren't a theoretical concept. Browser events, setTimeout, and fetch all use callbacks. The simplest example:
setTimeout(() => {
console.log("Dijalankan setelah 1 detik");
}, 1000);
console.log("Dijalankan lebih dulu");The output shows Dijalankan lebih dulu appearing first because setTimeout schedules the callback for later rather than running it immediately. This is your first look at asynchronous code — a topic we'll dissect fully in episodes 15 and 16.
Info
A small trigger that changes your perspective: a short arrow function without curly braces performs an implicit return, and functions are values that can be passed anywhere. These two facts are the key to reading almost all modern JavaScript code.
Episode 8 introduced arrow functions with concise syntax and lexically bound this, plus higher-order functions that treat functions as values. You also used inline callbacks — which feel strange at first, but will feel natural after episode 9.
Key takeaways:
this from the scope where they're written (lexical).this.setTimeout and events use callbacks that execute asynchronously.In the next episode 9 we'll cover the array methods map, filter, reduce, and find — transforming and filtering data in a functional style that changes how you process arrays. This is one of the most used skills in the JavaScript working world.