This seems to be a very common misconception that just won’t die. I keep running into it in blog posts, Twitter discussions, and even books. Here’s my attempt at setting things straight.

const creates an immutable binding

ES2015 const does not indicate that a value is ‘constant’ or immutable. A const value can definitely change. The following is perfectly valid ES2015 code that does not throw an exception:

const foo = {};

foo.bar = 42;

console.log(foo.bar);

// → 42

The only thing that’s immutable here is the binding. const assigns a value ( {} ) to a variable name ( foo ), and guarantees that no rebinding will happen. Using an assignment operator or a unary or postfix -- or ++ operator on a const variable throws a TypeError exception:

const foo = 27;

// Any of the following uncommented lines throws an exception.

// Assignment operators:

foo = 42;

foo *= 42;

foo /= 42;

foo %= 42;

foo += 42;

foo -= 42;

foo <<= 0b101010;

foo >>= 0b101010;

foo >>>= 0b101010;

foo &= 0b101010;

foo ^= 0b101010;

foo |= 0b101010;

// Unary `--` and `++`:

--foo;

++foo;

// Postfix `--` and `++`:

foo--;

foo++;

ES2015 const has nothing to do with immutability of values.

So, how to make a value immutable?

Primitive values, i.e. numbers, strings, booleans, symbols, null , or undefined , are always immutable.

var foo = 27;

foo.bar = 42;

console.log(foo.bar);

// → `undefined`

To make an object’s values immutable, use Object.freeze() . It has been around since ES5 and is widely available nowadays.

const foo = Object.freeze({

'bar': 27

});

foo.bar = 42; // throws a TypeError exception in strict mode;

// silently fails in sloppy mode

console.log(foo.bar);

// → 27

Note that Object.freeze() is shallow: object values within a frozen object (i.e. nested objects) can still be mutated. The MDN entry on Object.freeze() provides an example deepFreeze() implementation that can be used to make object values fully immutable.

Still, Object.freeze() only works on property-value pairs. There is currently no way to make other objects such as Date s, Map s, or Set s fully immutable.

There is a proposal to add immutable data structures to a future version of ECMAScript.

const vs. let

The only difference between const and let is that const makes the contract that no rebinding will happen.

Everything I wrote here so far are facts. What follows is entirely subjective, but bear with me.

Given the above, const makes code easier to read: within its scope, a const variable always refers to the same object. With let there is no such guarantee. As a result, it makes sense to use let and const as follows in your ES2015 code:

use const by default

by default only use let if rebinding is needed

if rebinding is needed ( var shouldn’t be used in ES2015)