Blog Logo

May 08 2025 ~ 6 min read

JavaScript Tips Every Beginner Should Know


hero image featuring the title JavaScript Tips I Wish I Knew Earlier

Real-world lessons that helped me write better code.

If you’ve spent any time writing JavaScript, you’ve probably run into moments where things don’t behave the way you expect. I definitely have. Over time, through trial and error and building actual projects, I’ve picked up a few habits and insights that have made my code cleaner and my life easier. This post is a collection of those tips. Hopefully, they’ll help you avoid some of the mistakes I made early on.

Use === Instead of == for Comparisons

In JavaScript, == tries to be helpful by converting values to the same type before comparing them. That sounds nice in theory, but in practice it can cause some very unexpected results.

0 == false      // true  
'' == 0         // true  
'123' == 123    // true

This kind of behavior can be really confusing. To avoid it, always use ===, which checks both value and type. It’s stricter, and that’s a good thing.

0 === false     // false  
'123' === 123   // false  
'hello' === 'hello' // true

It’s a simple habit that can save you a lot of debugging time.

Stick With let and const, Not var

The var keyword was how we used to declare variables in JavaScript, but it comes with quirks like function scoping and hoisting. That means variables declared with var can behave in ways that are hard to reason about.

if (true) {  
  var x = 10;  
}  
console.log(x); // 10 (even though it's outside the block)

With let and const, you get block scoping, which is more predictable and helps avoid accidental bugs.

if (true) {  
  let y = 20;  
}  
console.log(y); // ReferenceError: y is not defined

Use const when you don’t plan to reassign the variable, and let when you do. It makes your code easier to read and reason about.

Avoid Changing Arrays or Objects Directly

In JavaScript, arrays and objects are passed by reference. That means if you change them, those changes affect the original as well. This can lead to side effects you didn’t intend.

const original = [1, 2, 3];  
const copy = original;  
copy.push(4);  
  
console.log(original); // [1, 2, 3, 4]

Instead, make a copy first. That way, you keep your original data safe.

const original = [1, 2, 3];  
const copy = [...original];  
copy.push(4);  
  
console.log(original); // [1, 2, 3]  
console.log(copy);     // [1, 2, 3, 4]

The same idea applies to objects:

const obj = { a: 1, b: 2 };  
const newObj = { ...obj, b: 3 };  
  
console.log(newObj); // { a: 1, b: 3 }

Arrays and objects in JavaScript are passed by reference, meaning changes to them affect the original. While this behavior can be helpful in certain cases, it often leads to bugs or unintended side effects if not handled carefully.

In some cases, directly modifying the original data is intentional and can be efficient. But in other scenarios, when using frameworks like React or following functional programming practices, preserving immutability is important for predictable behavior. This is important in React, where immutability helps in detecting changes and triggering re-renders correctly. Using copies instead of direct mutations makes your code safer, easier to debug, and more maintainable.

In general, when in doubt, copy, not because mutation is always bad, but because predictability is almost always good.

Get Comfortable With Closures

Closures let a function remember the variables from where it was created. That sounds simple, but it unlocks a lot of powerful patterns in JavaScript.

function createCounter() {
  let count = 0;
  return function () {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

Even though the outer function has finished running, the inner function keeps access to count. Closures are used all over the place, from timers to state management.

Understand How this Works

The value of this in JavaScript depends on how a function is called. That’s why you can sometimes get strange results when using regular functions inside other functions or callbacks.

const person = {
  name: 'Sam',
  greet: function () {
    setTimeout(function () {
      console.log(`Hi, I'm ${this.name}`);
    }, 1000);
  }
};

person.greet(); // "Hi, I'm undefined"

Arrow functions help here because they don’t create their own this. They just use whatever this was already in scope.


const person = {
  name: 'Sam',
  greet: function () {
    setTimeout(() => {
      console.log(`Hi, I'm ${this.name}`);
    }, 1000);
  }
};

person.greet(); // "Hi, I'm Sam"

So when you’re inside an object and using callbacks, arrow functions are often the safer choice.

Use Default Parameters

Instead of writing manual checks for undefined, you can use default values directly in the function parameters. It keeps your code cleaner and avoids unnecessary logic.

function greet(name = 'Guest') {
  return `Hello, ${name}`;
}

console.log(greet());        // Hello, Guest
console.log(greet('Sam')); // Hello, Sam

It’s a small thing, but it makes your function signatures more expressive and your code shorter.

Destructure for Readability

Destructuring lets you extract values from arrays or objects in a single line. It makes your code more readable and avoids repetitive access patterns.

const user = { name: 'Sam', age: 30 };
const { name, age } = user;

console.log(name); // Sam
console.log(age);  // 30

You can also use it right inside function parameters:

function printUser({ name, age }) {
  console.log(`${name} is ${age} years old`);
}

printUser(user); // Sam is 30 years old

This really shines when working with APIs or data-heavy components.

Conclusion

JavaScript is a flexible and powerful language, but that flexibility means it’s easy to fall into confusing patterns if you’re not careful. These tips have helped me write cleaner, more reliable code, and understand how the language actually works under the hood. Whether you’re just getting started or you’ve been writing JavaScript for a while, I hope at least one of these ideas helps make your code better.

Share this post:


Headshot of Samarth

Hi, I'm Samarth. I'm a software engineer based in Los Angeles. You can follow me on Twitter, see some of my work on GitHub, or read more about me on LinkedIn.