Skip to main content

Types

JavaScript values fall into two categories: primitives and complex types. Understanding how each is accessed determines how changes to one variable affect others.

1.1 Primitives

When you access a primitive type, you work directly on its value. The primitive types are:
  • string
  • number
  • boolean
  • null
  • undefined
  • symbol
  • bigint
const foo = 1;
let bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9
Because bar holds a copy of the value, reassigning bar has no effect on foo.
Symbols and BigInts cannot be faithfully polyfilled. Do not use them when targeting browsers or environments that don’t support them natively.

1.2 Complex types

When you access a complex type, you work on a reference to its value. The complex types are:
  • object
  • array
  • function
const foo = [1, 2];
const bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // => 9, 9
Both foo and bar point to the same array in memory. Mutating through either reference affects both.

References

Use const by default and let only when reassignment is necessary. Avoid var entirely.

2.1 Prefer const

Use const for all of your references; avoid using var. eslint: prefer-const, no-const-assign
Ensuring references can’t be reassigned helps prevent bugs and makes code easier to reason about.
const a = 1;
const b = 2;

2.2 Use let for reassignable references

If you must reassign a reference, use let instead of var. eslint: no-var
let is block-scoped rather than function-scoped like var. This makes its behavior more predictable and avoids accidental leaks.
// good, use the let.
let count = 1;
if (true) {
  count += 1;
}

2.3 Block scope vs. function scope

Both let and const are block-scoped, whereas var is function-scoped.
// const and let only exist in the blocks they are defined in.
{
  let a = 1;
  const b = 1;
  var c = 1;
}
console.log(a); // ReferenceError
console.log(b); // ReferenceError
console.log(c); // Prints 1
In the example above, a and b are block-scoped — accessing them outside the block throws a ReferenceError. c is function-scoped via var, so it leaks out of the block and remains accessible.

Build docs developers (and LLMs) love