Modern JavaScript You Need: let, const, Arrow Functions, Destructuring and Modules

MERN Stack Full Course: MongoDB, Express, React and Node.js · Foundations · 5 min read · Updated

Modern JavaScript in one example

  1. Real apps pass around arrays of objects, such as a list of jobs.
  2. Arrow functions with map and filter transform lists without a loop.
  3. Destructuring pulls fields out of an object in one line.
  4. Modules split code into files. export shares a value and import uses it.
  5. const by default, let when a value changes, and never var. The spread syntax copies without changing the original.

MERN code is written in the JavaScript of the last ten years, often called ES6 or ES2015+. If you learned JavaScript from older tutorials, some of the syntax will look new. Everything below appears again and again in the server and in React, so it is worth meeting it once, calmly, before the project starts.

Run the tour file after reading each section and change values to see what happens. Learning by changing working code is faster than only reading.

const and let, never var

const makes a variable that cannot be assigned again. let makes one that can. Use const by default and let only when the value must change, such as a counter. A const object can still be changed inside (you can add a property), but you cannot point the name at a different object. The old var has confusing scope rules, so modern code never uses it.

Template strings and objects

Back ticks create template strings, which can hold values: ` Applied to ${company} . Objects group related values, and **shorthand** lets you write { role } instead of { role: role }` when the variable has the same name. You will write this constantly when building API responses.

Destructuring and spread

Destructuring pulls values out of objects and arrays into variables in one line: const { role, salary: { max } } = job. In React you will write function JobCard({ job, onStatusChange }), which is destructuring of the props object right in the parameter list.

Spread (...) copies the contents of an object or array into a new one. { ...job, status: 'interview' } is a new object with all the old fields and a changed status, and the original is untouched. This matters a great deal: React state must be replaced, not edited in place, and spread is how you do it.

Arrow functions and array methods

An arrow function is a short function: (j) => j.status === 'applied'. Combined with the array methods map, filter, find and reduce, it replaces most for loops. map turns every item into something else (a list of jobs into a list of cards), filter keeps some items, find returns the first match, and reduce folds a list into one value, such as counts per status.

Optional chaining and defaults

maybe.company?.name returns undefined instead of crashing when company is missing. ?? gives a default only when the left side is null or undefined: name ?? 'unknown'. The older || replaces every falsy value, including 0 and an empty string, which is a common source of bugs, for example when a salary of 0 is replaced by a default.

Modules: import and export

Each file is a module. export makes something available to other files, and import brings it in. In Node.js, use "type": "module" in package.json (the server in this course does) and write the .js extension in relative imports: import { formatSalary } from './helpers.js'.

The tour

// Lesson 3: the modern JavaScript used in every MERN app.   Run:  node examples/03-javascript/es6-tour.js

// const and let (never var)
const company = 'Acme Logistics';
let attempts = 1;
attempts += 1;

// template strings
console.log(`Applied to ${company}, attempt ${attempts}`);

// objects, destructuring and shorthand
const job = { id: 7, role: 'Dispatcher', salary: { min: 18000, max: 24000 }, tags: ['night shift', 'local'] };
const { role, salary: { max }, tags: [firstTag] } = job;
console.log(role, max, firstTag);

// spread: copy and change without touching the original (React state depends on this)
const updated = { ...job, status: 'interview' };
console.log(job.status, updated.status); // undefined interview
const moreTags = [...job.tags, 'full time'];
console.log(moreTags);

// arrow functions and array methods
const jobs = [
  { id: 1, role: 'Teller', status: 'applied' },
  { id: 2, role: 'Dispatcher', status: 'interview' },
  { id: 3, role: 'Driver', status: 'applied' },
];
const applied = jobs.filter((j) => j.status === 'applied');
const roles = jobs.map((j) => j.role);
const firstInterview = jobs.find((j) => j.status === 'interview');
const counts = jobs.reduce((acc, j) => ({ ...acc, [j.status]: (acc[j.status] || 0) + 1 }), {});
console.log(applied.length, roles, firstInterview.role, counts);

// optional chaining and default values
const maybe = { company: { name: 'Northwind' } };
console.log(maybe.company?.name ?? 'unknown', maybe.owner?.name ?? 'no owner');

// ES modules: export in one file, import in another (see helpers.js)
import { formatSalary } from './helpers.js';
console.log(formatSalary(job.salary));
export const formatSalary = ({ min, max }) => `${min.toLocaleString('en-IN')} - ${max.toLocaleString('en-IN')}`;

Run it with node examples/03-javascript/es6-tour.js. Read the output next to the code. Pay attention to the line that prints undefined interview: it proves that spread made a copy, because the original job still has no status.

Your task

  1. Run the tour and read each printed line against the code that produced it.
  2. Use filter and map together to print only the roles of jobs whose status is applied.
  3. Use reduce to total the salary.max of an array of three jobs.
  4. Write a function withStatus(job, status) that returns a copy of the job with a new status and never changes the original. Check that the original is unchanged.

How to check it worked

  • node runs the file with no errors.
  • Your withStatus returns a new object and the original job still has its old status.

Summary

  • const by default, let when needed, never var.
  • Destructuring takes values out; spread copies values in. Together they make non-mutating updates easy.
  • map, filter, find and reduce replace most loops.
  • Use ?. and ?? for safe reads and honest defaults.

Download the solution (mern-lesson-03.zip)

Frequently asked questions

What is the difference between == and ===?

=== compares value and type without converting, so 1 === "1" is false. == converts first and gives surprising results. Use === everywhere.

Why does React need me to copy objects instead of changing them?

React decides whether to redraw by checking if state is a new value. If you edit an object in place, the reference is the same and React may not notice. Spread creates a new object, so React sees the change.

Do I need to learn classes and prototypes first?

Not for this course. Modern React uses function components, and the server code here uses plain functions and modules. Classes are useful to know later.