JavaScript for impatient programmers (beta)
Please support this book: buy it or donate
(Ad, please don’t block.)

9. Variables and assignment

These are JavaScript’s main ways of declaring variables:

Before ES6, there was also var. But it has several quirks, so it’s best to avoid it in modern JavaScript. You can read more about it in “Speaking JavaScript”.

9.1. let

Variables declared via let are mutable:

let i;
i = 0;
i = i + 1;
assert.equal(i, 1);

You can also declare and assign at the same time:

let i = 0;

9.2. const

Variables declared via const are immutable. You must always initialize immediately:

const i = 0; // must initialize

assert.throws(
  () => { i = i + 1 },
  {
    name: 'TypeError',
    message: 'Assignment to constant variable.',
  }
);

9.2.1. const and immutability

In JavaScript, const only means that the binding (the association between variable name and variable value) is immutable. The value itself may be mutable, like obj in the following example.

const obj = { prop: 0 };

obj.prop = obj.prop + 1;
assert.equal(obj.prop, 1);

However:

const obj = { prop: 0 };

assert.throws(
  () => { obj = {} },
  {
    name: 'TypeError',
    message: 'Assignment to constant variable.',
  }
);

9.2.2. const and loops

You can use const with for-of loops, where a fresh binding is created for each iteration:

const arr = ['hello', 'world'];
for (const elem of arr) {
  console.log(elem);
}
// Output:
// 'hello'
// 'world'

In plain for loops, you must use let, however:

const arr = ['hello', 'world'];
for (let i=0; i<arr.length; i++) {
  const elem = arr[i];
  console.log(elem);
}

9.3. Deciding between let and const

I recommend the following rules to decide between let and const:

  Exercise: const

exercises/variables-assignment/const_exrc.js

9.4. Variables are block-scoped

The scope of a variable is the region of a program where it can be accessed.

Like in most modern programming languages, variables declared via let and const are block-scoped: they can only be accessed from within the block that the are declared in.

{
  const x = 0;
}
assert.throws(
  () => x + 1,
  {
    name: 'ReferenceError',
    message: 'x is not defined',
  }
);

The curly braces enclose a code block. x only exists within that block and can’t be access outside it.

9.4.1. Shadowing and blocks

You can’t declare the same variable twice at the same level. You can, however, nest a block and use the same variable name x that you used outside the block:

const x = 1;
assert.equal(x, 1);
{
  const x = 2;
  assert.equal(x, 2);
}
assert.equal(x, 1);

Inside the block, the inner x is the only accessible variable with that name. The inner x is said to shadow the outer x. Once you leave the block, you can access the old value again.

  More information on variable scopes and closures

For more on variable scopes and closures, consult the corresponding chapter later in this book.

  Quiz

See quiz app.