15 JavaScript Tricks Transforming Beginners to Pros

Looking to improve your JavaScript skills? Whether you’re just starting out or have experience under your belt, there’s always something new to learn. In this article, you’ll discover 15 JavaScript techniques that can help elevate your code from basic to pro-level.

We’ll compare how a novice might write code versus how an experienced developer would approach the same problem—resulting in cleaner, more efficient code. These examples also highlight key ES6+ features that make JavaScript more powerful and maintainable.

By the end, you’ll be able to refactor your code for improved readability and performance.

Let’s dive in!

1. Use the ternary operator for conditional assignment
Instead of lengthy if-else statements, the ternary operator offers a compact syntax for assigning values based on conditions.

// Beginner
let age = 18;
let status;
if (age >= 18) {
  status = "adult";
} else {
  status = "minor";
}

// Pro
let age = 18;
let status = age >= 18 ? "adult" : "minor";

Keep it concise, but avoid nesting too many ternaries—they can quickly become hard to read.

2. Use the spread operator to copy and merge objects and arrays
The spread operator (...) simplifies merging or copying data structures.

// Beginner
let person = { name: "John", age: 35 };
let address = { city: "New York", country: "USA" };
let combined = Object.assign({}, person, address);

// Pro
let combined = { ...person, ...address };

This approach is neater and doesn’t mutate original objects.

3. Use the rest parameter to handle variable arguments
Gather multiple arguments into a single array with ease using the rest parameter.

// Beginner
function sum() {
  let args = Array.prototype.slice.call(arguments);
  return args.reduce((acc, curr) => acc + curr, 0);
}

// Pro
function sum(...args) {
  return args.reduce((acc, curr) => acc + curr, 0);
}

This makes your function more flexible and readable.

4. Use destructuring to simplify variable assignment
Accessing properties of objects or arrays becomes much more elegant with destructuring.

// Beginner
let name = person.name;
let age = person.age;

// Pro
let { name, age } = person;

You can also assign default values and rename variables during destructuring.

5. Use template literals for dynamic strings
Template literals make string composition smoother and support multi-line formatting.

// Beginner
let message = "Hello, my name is " + username + " and I am " + age + " years old.";

// Pro
let message = `Hello, my name is ${username} and I am ${age} years old.`;

Backticks and ${} make your code both cleaner and easier to read.

6. Use arrow functions for shorter syntax
Arrow functions are concise and bind this lexically.

// Beginner
let squares = numbers.map(function (num) {
  return num * num;
});

// Pro
let squares = numbers.map(num => num * num);

They’re especially useful for one-liners and callbacks.

7. Use default parameters in functions
Default values simplify your function logic by removing conditional checks.

// Beginner
function greet(name, message) {
  name = name || "Guest";
  message = message || "Welcome";
  return message + ", " + name + "!";
}

// Pro
function greet(name = "Guest", message = "Welcome") {
  return `${message}, ${name}!`;
}

Cleaner, with fewer lines of code.

8. Use logical operators for short-circuit evaluation
Shorten conditional logic with && or ||.

// Beginner
if (value > 5) {
  console.log("Value is greater than 5");
}

// Pro
value > 5 && console.log("Value is greater than 5");

Simple, but effective in the right context.

9. Use bitwise operations for performance tricks
Bitwise operators can offer performance gains in certain cases.

// Beginner
if (value % 2 === 0) {
  console.log("Even");
} else {
  console.log("Odd");
}

// Pro
(value & 1) ? console.log("Odd") : console.log("Even");

Use sparingly, as readability may suffer.

10. Use includes() to check for values in arrays
includes() offers a cleaner alternative to indexOf().

// Beginner
if (months.indexOf("Apr") !== -1) {
  console.log("Found April");
}

// Pro
if (months.includes("Apr")) {
  console.log("Found April");
}

It’s readable and works well with conditionals.

11. Use Object.is() for accurate comparisons
More precise than === in edge cases.

// Beginner
console.log(NaN === NaN); // false

// Pro
console.log(Object.is(NaN, NaN)); // true

Great when dealing with tricky values like NaN or -0.

12. Use startsWith() and endsWith() for string checks
Much more readable than slicing strings.

// Beginner
if (str.slice(0, 5) === "Hello") { ... }

// Pro
if (str.startsWith("Hello")) { ... }

Cleaner and more semantic.

13. Use optional chaining to access deeply nested values
Avoids errors by short-circuiting on null or undefined.

// Beginner
if (person && person.address && person.address.city) {
  city = person.address.city;
}

// Pro
let city = person?.address?.city;

Safe, and prevents common runtime errors.

14. Use nullish coalescing for fallback values
Avoids false positives from falsy values like "", 0, or false.

// Beginner
let name = "" || "Guest"; // "Guest" (not always desired)

// Pro
let name = "" ?? "Guest"; // ""

Use it when you only want to treat null or undefined as missing.

15. Use for-of to iterate over iterable values
Simplifies loops for arrays and other iterable objects.

// Beginner
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

// Pro
for (let item of arr) {
  console.log(item);
}

Clean, modern, and expressive.

Conclusion
These JavaScript techniques go a long way in making your code more modern, concise, and maintainable. By integrating these tips into your daily coding habits, you’ll not only write better code but also think more like a seasoned developer. Happy coding!

What to read next