Const in JavaScript: When to Use It and Is It Necessary

Const in JavaScript: when to use it and is it necessary?

There are two aspects to your questions: what are the technical aspects of using const instead of var and what are the human-related aspects of doing so.

The technical difference is significant. In compiled languages, a constant will be replaced at compile-time and its use will allow for other optimizations like dead code removal to further increase the runtime efficiency of the code. Recent (loosely used term) JavaScript engines actually compile JS code to get better performance, so using the const keyword would inform them that the optimizations described above are possible and should be done. This results in better performance.

The human-related aspect is about the semantics of the keyword. A variable is a data structure that contains information that is expected to change. A constant is a data structure that contains information that will never change. If there is room for error, var should always be used. However, not all information that never changes in the lifetime of a program needs to be declared with const. If under different circumstances the information should change, use var to indicate that, even if the actual change doesn't appear in your code.

Why most of the time should I use const instead of let in JavaScript?

Basically,

  • use let if the variable's value will change during the code
  • use const if it won't and you / your team want to use const in those situations in the project you're working on; it's a matter of style

If you do use const, then it's surprising how often it turns out that the guidelines above mean you use const because you end up not needing to change a variable's value (if you're following the usual rules of keeping your functions of reasonable size and such). (Well, it surprised me, anyway...)

Using const when the variable's¹ value is not meant to change accomplishes a few things:

  1. It tells others reading your code that you don't intend the value to change.

  2. It gives you a nice proactive error if you change the code so it writes to that variable. (A decent IDE can flag this up proactively, but if not, you'll get the error when running the code.) You can then make an informed, intentional decision: Should you change it to let, or did you not mean to change that variable's value in the first place?

  3. It gives a hint to the JavaScript engine's optimizer that you won't be changing that variable's value. While the engine can frequently work that out through code analysis, using const saves it the trouble. (Caveat: I have no idea whether this is actually useful to the JavaScript engine. It seems like it would be, but runtime code optimization is a very complicated and sometimes non-intuitive process.)


¹ Yes, it's funny to use the term "variable" to refer to something that by definition doesn't vary. :-) The specification's term is "binding," but I bet you won't hear people talking about "bindings" in everyday conversation anytime soon... So the aggregate term will probably remain "variable" except when we can specifically refer to something as a "constant."

for...of loop. Should I use const or let?

Why use const and when to use let in for...of loops?

If there are no assignments to the identifier within the loop body, it's a matter of style whether you use let or const.

Use const if you want the identifier within the loop body to be read-only (so that, for instance, if someone modifies the code later to add an assignment, it's a proactive error). Use let if you want to be able to assign to it (because you have an assignment in your code, or you want someone to be able to add one later without changing the declaration).

You can do this with for-of and for-in loops. A for loop's control variable is normally not constant (since in the normal case you update it in the "update" clause of the for; if you don't, for may be the wrong loop to use), so you normally use let with it.


For clarity, here's an example with an assignment within the loop body:

for (let str of ["a", " b", " c "]) {
str = str.trim();
// ^^^^^----- assignment to the identifier
console.log(`[${str}]`);
}

When to use const with objects in JavaScript?

it is a common misconception around the web, CONST doesn't creates immutable variables instead it creates immutable binding.

eg.

 const temp1 = 1;
temp1 = 2 //error thrown here.

But

 temp1.temp = 3 // no error here. Valid JS code as per ES6

so const creates a binding to that particular object. const assures that variable temp1 won't have any other object's Binding.

Now coming to Object. we can get immutable feature with Object by using Object.freeze

const temp3 = Object.freeze( {a:3,b:4})
temp3.a = 2 // it wont update the value of a, it still have 3
temp3.c = 6 // still valid but wont change the object

Proper use of const for defining functions

There's no problem with what you've done, but you must remember the difference between function declarations and function expressions.

A function declaration, that is:

function doSomething () {}

Is hoisted entirely to the top of the scope (and like let and const they are block scoped as well).

This means that the following will work:

doSomething() // works!
function doSomething() {}

A function expression, that is:

[const | let | var] = function () {} (or () =>

Is the creation of an anonymous function (function () {}) and the creation of a variable, and then the assignment of that anonymous function to that variable.

So the usual rules around variable hoisting within a scope -- block-scoped variables (let and const) do not hoist as undefined to the top of their block scope.

This means:

if (true) {
doSomething() // will fail
const doSomething = function () {}
}

Will fail since doSomething is not defined. (It will throw a ReferenceError)

If you switch to using var you get your hoisting of the variable, but it will be initialized to undefined so that block of code above will still not work. (This will throw a TypeError since doSomething is not a function at the time you call it)

As far as standard practices go, you should always use the proper tool for the job.

Axel Rauschmayer has a great post on scope and hoisting including es6 semantics: Variables and Scoping in ES6

Are there constants in JavaScript?

Since ES2015, JavaScript has a notion of const:

const MY_CONSTANT = "some-value";

This will work in pretty much all browsers except IE 8, 9 and 10. Some may also need strict mode enabled.

You can use var with conventions like ALL_CAPS to show that certain values should not be modified if you need to support older browsers or are working with legacy code:

var MY_CONSTANT = "some-value";

Does it make sense to use const for all variables that will never be changed?

The use of const is up to the individual. Optimization of most javascript engines work best if you pretend that javascript is strongly typed. const would thus seem like a good idea.

Some facts.

  • MDN states that consts are block scoped like let. This is only true
    in strict mode.
  • Consts must be assigned a value on declaration. Only true in strict
    mode.
  • Consts can not be reassigned. This is true in both strict and normal
    but in normal javascript assigning to a constant fails silently which
    represents a source of hard to find bugs. (NOTE there is no good
    argument for not using strict mode)

The differences as an example

function log(d){console.log(d);}
(function (){
if(true){
const a = 10; // correctly formed use of constant
const b; // does not fail
log(a); // 10;
log(b); // undefined
b = 10; // nothing happens. If you have forgoten this is a constant
// you will have a hard time knowing this assignment is failing
log(b); // undefined
}
// scope not respected
log(a); // 10 const should have block scope. This does not seem to be true
// in normal javascript
})();

// function in strict mode
// not this is an example only and can not run. It is a compilation of several functions
(function (){
"use strict";
if(true){
const a = 10;
const b; // SyntaxError: Unexpected token. Javascript parsing
// stops here and the function will never be called
a = 20; // TypeError: Assignment to constant variable
}
// scope is respected
log(a); // ReferenceError: a is not defined
})();

As you can see there is a big difference between using const in strict mode and not. It would be foolhardy to use constants in anything but strict mode.

Performance.
Chrome was very early in its adoption of const, I have memory of using const at least 3 years ago. As I specialize in graphics, performance is critical. I reasoned that a const would provide a much needed performance advantage, much the same way #define does in C/C++ by simple code insertion of the constant value. Saddly by the end of that day I was completely turned against the use of const because of it terrible performance.

Since then it has improved.

jsperf "Consts V Vars"

Using const is consistently slower in all tests but it is marginal and too close to call. The only exception being block scope declaration where it was about 1/3rd the speed of var and let. One surprising finding is that let is now very fast on Chrome Beta, a month ago I would not go near it, this fact is the reason for my answer.

OP asked...
Does it make sense to use const for all variables that will never be changed?

A year ago I would have said "NEVER USE IT". A few months ago I would have said, "Have a good reason but var is better".

Now my answer is most definitely use constants whenever you intend a variable to never change. Constants out performs literals and are as good as var.

const c = 10;
var v = 10;
var a = 10; // this is slower
var a = c; // this is 20% faster
var a = v; // this is about < 1% faster than const.

At the rate of change browsers undergo, and from the performance changes in the last few months of both let and conston chrome. I would suspect that constants will out perform vars by the end of the year. (please note I am using Chrome Beta 47)

The tests I have performed do not provide much room for code optimisation, so I would guess there is additional performance in using const that is not evident in the tests.

A constant by its very nature is strongly typed, this gives the javascript optimisation algorithms something to use to provide additional performance.

Using constants makes for better code quality. Javascript (even strict mode) can hide a bug for a long time, using constants reduces the risk of bad assignments, accidental type conversion, and more.

BUT
I place a big warning on the use of const. ONLY USE const in strict mode, its behaviour in normal javascript is dangerous and will only cause you problems.

const vs let when calling require

const can be normally used when you don't want your program

  1. to assign anything to the variable

    "use strict";
    const a = 1;
    a = 2;

    will produce TypeError: Assignment to constant variable..

  2. to use the variable without explicitly initializing.

    "use strict";
    const a;

    will produce SyntaxError: Unexpected token ;

Simply put, I would say,

  • use const whenever you want some variables not to be modified

  • use let if you want the exact opposite of const

  • use var, if you want to be compatible with ES5 implementations or if you want module/function level scope.

Use let only when you need block level scoping, otherwise using let or var would not make any difference.

Is there a use for NOT using var, let or const?

If no var, let or const statement is used like:

x = 100;

than the variable gets assigned to the global scope, or reassigned where it is found in the scope, what very often is not the desired behavior, since that leads to cluttering in the scope, or variable overriding, so strange bugs.

To reassign a variable wherever it is found in the scope, just us the same method as above:

x = 101;

If you have something like this:

//global scope
var z = 40;

(function () {
//scope »level 1«
var x = 100;
//implicitly declared in global scope
y = 300;

z += 1;

console.log(z); //41

(function () {
//scope »level 2«
x = 101;
z += 1;
})();

console.log(x) // 101;
console.log(y) // 300;
console.log(z) // 42;

})();

console.log(x) // undefined;
console.log(y) // 300;
console.log(z) // 42;

A basic example of using the scope chain in a useful way:

//create a »working scope«
//to prevent cluttering the global
(function () {
var getID = (function () {
//hide the id variable in child scope
//to prevent it from modification
var id = 0;

return function () {
//modify and return values
//from this scope
id += 1;
return id;
}
})();

//that doen't make much sense,
//but is also a example of using a
//working scope
var usedIds = Array.prototype.slice
.call(document.querySelectorAll('.a-class'))
.map(function (node) {
var id = 'my-id-' + getID();
node.id = id;
return id;
});

// export/expose variables to the global scope explicitly
window.globallyNeeded = usedIds;
})();


Related Topics



Leave a reply



Submit