388

I've recently come across the const keyword in JavaScript. From what I can tell, it is used to create immutable variables, and I've tested to ensure that it cannot be redefined (in Node.js):

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'

I realise that it is not yet standardized across all browsers - but I'm only interested in the context of Node.js V8, and I've noticed that certain developers / projects seem to favor it heavily when the var keyword could be used to the same effect.

  • When is it appropriate to use const in place of var?
  • Should it be used every time a variable which is not going to be re-assigned is declared?
  • Does it actually make any difference if var is used in place of const or vice-versa?
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
axdg
  • 4,025
  • 3
  • 13
  • 7
  • 1
    That doesn't seems to be standardized yet (maybe in EC6 ?). You'll find additional informations about it here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const – Sebastien C. Jan 20 '14 at 15:02

18 Answers18

492

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.

Tibos
  • 27,507
  • 4
  • 50
  • 64
  • 6
    Cheers, I assumed that Mozilla / Google wouldn't have added const support to JS engines for no reason. I'll make sure to use const where applicable. – axdg Jan 20 '14 at 15:46
  • 9
    `const` objects seem to be mutable, so I'm not sure how strict the JS compiler really is. Maybe "use strict" mode makes a difference too. – Rudie Nov 27 '15 at 21:44
  • 16
    @Rudie The feature you are looking for is called [freezing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) the object. `const` just prevents reassigning the "variable" to another value. `const a = {}; a = {};` will throw an error in strict mode. – Tibos Nov 28 '15 at 10:42
  • I use const in general instead of let for most variables, just as in Java I add final to most variable declarations. – coding May 17 '16 at 16:05
  • your answer is not 100% accurate https://mathiasbynens.be/notes/es6-const const CAN change in certain ways – PositiveGuy Jul 15 '16 at 17:59
  • In a [similar question](http://stackoverflow.com/questions/23483926/const-vs-var-while-requiring-a-module) someone added a comment suggesting using const can have a lower performance and they reference [this test](https://jsperf.com/const-vs-var). Is that only the case initially due to the extra compile-time work? Could that be expected to result in a better performance in the long run? – Hagelt18 Mar 10 '17 at 17:00
  • 3
    `If there is room for error, var should always be used`. Today this no longer applies, with tools like ESLint pointing at `const` violation right away. – vitaly-t Jun 13 '17 at 17:14
  • @vitaly-t What about if you're writing a library/module to be included in other code? Your ESLinted declaration could be used in a case that you have no control over and very well would have the opportunity to be overwritten. – Mark Carpenter Jr Nov 17 '17 at 15:42
  • @MarkCarpenterJr If it's absolutely necessary to ensure misuse of your code doesn't happen, don't release it, otherwise encapsulate your data and provide a getter/function that returns a copy of your internal data (primitives such as numbers don't need explicit copying). – Chinoto Vokro Dec 19 '18 at 01:32
  • @ChinotoVokro That's cool if you're making your code base public, extensible and/or conforming to a design pattern. What about internal proprietary internal applications? not to mention Legacy codebases that won't get burnt and rebuilt but just get extended until EOL? – Mark Carpenter Jr Dec 19 '18 at 16:19
  • @MarkCarpenterJr If you can't change your own internal applications, then I guess you're screwed; otherwise I'm sure you can do a little modification if it matters, and if something breaks, good, then it can be fixed to not do the thing it shouldn't have done in the first place. – Chinoto Vokro Dec 20 '18 at 22:00
  • 1
    To All Reading about const changing, you have to remember how variables to objects work, your variable is nothing but an address location to the object, so while the object is mutable the pointer to that object when defined with const is not. – Barkermn01 May 12 '20 at 11:35
  • I know this is ancient, but it would be good to have an update pointing out that `var` is not the alternative to `const`, `let` is. Unless your concern is old browser compatibility, the choice should be between using `const` or `let`. `let` allows reassignment like `var` but doesn't have the weird hoisting behavior that almost nobody intentionally wants. – Vectorjohn Sep 07 '22 at 22:43
78

2017 Update

This answer still receives a lot of attention. It's worth noting that this answer was posted back at the beginning of 2014 and a lot has changed since then. support is now the norm. All modern browsers now support const so it should be pretty safe to use without any problems.


Original Answer from 2014

Despite having fairly decent browser support, I'd avoid using it for now. From MDN's article on const:

The current implementation of const is a Mozilla-specific extension and is not part of ECMAScript 5. It is supported in Firefox & Chrome (V8). As of Safari 5.1.7 and Opera 12.00, if you define a variable with const in these browsers, you can still change its value later. It is not supported in Internet Explorer 6-10, but is included in Internet Explorer 11. The const keyword currently declares the constant in the function scope (like variables declared with var).

It then goes on to say:

const is going to be defined by ECMAScript 6, but with different semantics. Similar to variables declared with the let statement, constants declared with const will be block-scoped.

If you do use const you're going to have to add in a workaround to support slightly older browsers.

James Donnelly
  • 126,410
  • 34
  • 208
  • 218
  • 6
    Great answer - although i already read the article on MDN. As I said, I was more interested in whether **V8 specifically** was actually going to treat const differently to var. I think @Tibos cleared that up. – axdg Jan 20 '14 at 15:43
  • James thanks for pointing out the support aspect. imho all javascript answers should include a browser support breakdown. nicely explained – hubson bropa Apr 09 '15 at 15:20
  • 4
    Note ES6 has received a feature-freeze in August 2014. In July 2015 the standard was officially released. If you are reading this now, it means that you should follow the accepted answer as outlined if your code is managed by an up-to-date engine. – Filip Dupanović Oct 12 '15 at 23:33
  • The OP question is node.js specific – Nicu Surdu Apr 06 '17 at 14:53
  • @NicolaeSurdu sure. It's also from January 2014, so is probably mostly redundant now in 2017. – James Donnelly Apr 06 '17 at 15:01
  • The revision history of this answer (and any other answer for that matter) is interesting to very few readers. It would be better if the current version of the answer is as if it was written today. If there is version-dependent information to be kept, it can be marked as such, e.g. "For versions prior to X" or "For versions between X and Y". – Peter Mortensen Mar 23 '21 at 04:22
57

For why to use const, Tibos's answer's great.

But you said:

From what I can tell, it is used to create immutable variables

That is wrong. Mutating a variable is different from reassigning:

var hello = 'world' // Assigning
hello = 'bonjour!' // Reassigning

With const, you can not do that:

const hello = 'world'
hello = 'bonjour!' // Error

But you can mutate your variable:

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.

So, any process that changes the variable's value without using the = sign is mutating the variable.

Note: += for example is ... reassigning!

var a = 5
a += 2 // Is the same as a = a + 2

So, the bottom line is: const doesn't prevent you from mutating variables; it prevents you from reassigning them.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
math2001
  • 4,167
  • 24
  • 35
  • 7
    your statement "any process that changes the variable's value *without* using the `=` sign is muting" is technically wrong. For example, `const marks=[92,83]; marks[2]=95; console.log(marks)` will output `[92, 83, 95]`. `marks` has been mutated, via equals sign. – chharvey May 03 '17 at 03:45
  • 10
    *"But you said: <> That is **wrong**. Mutating a variable is different from reassigning"* No, it isn't. Reassigning is mutating the variable. You're talking about mutating the object the reference in the variable refers to. That's a different thing entirely. – T.J. Crowder Aug 04 '17 at 08:29
  • Got here because I am trying to understand `const` in the context of arrays (similar to the example @chharvey used). In the case of `const countArray = countup(n - 1); countArray.push(n);` the `const` is re-assigned each time. So why use `const` and not `var`? – YCode Mar 20 '20 at 16:05
  • 2
    @YCode no. when you use `const countArray`, it will *never* be reassigned. You can still push to the array, which changes its members and length, but we don't call that reassigning. you use `const` instead of `let` or `var` when you want to prevent reassigning. BTW if you *do* want to allow reassigning, `let` is almost always better than `var`. – chharvey Mar 20 '20 at 17:41
  • @chharvey Thanks! Your response led me to "pass by value vs pass by reference", a new concept, and a strange one--where value modification ≠ reassignment. Anyone needing further explanation should check answers here: https://stackoverflow.com/q/46131828/5965865 – YCode Mar 22 '20 at 20:06
40

To integrate the previous answers, there's an obvious advantage in declaring constant variables, apart from the performance reason: if you accidentally try to change or redeclare them in the code, the program will respectively not change the value or throw an error.

For example, compare:

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! Assigning a value variable in an 'if' condition
    console.log (x)
}

with:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') {
    console.log (y)
}

or

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/* Complex code */

var x = 0

with

// Will reassign y and cause trouble

var y = "SECRET"

/* Complex code */

var y = 0
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
janesconference
  • 6,333
  • 8
  • 55
  • 73
  • You should say that this "immutable" behaviour is only applicable to Strings, Basic Types. Using Objects, Arrays etc. it is possible to change the values but it is not possible to re-assign an new "Object", e.g. const a = ["a","b"]; a = []; will throw an error otherwise it is possible – Fer To Feb 09 '16 at 15:03
  • You should have an example where you try and change the value of a constant as well. – Joshua Pinter Mar 25 '16 at 19:13
  • Using const is very much like access modifiers, true immutability isnt the goal. – StingyJack Sep 30 '16 at 11:37
32

const is not immutable.

From the MDN:

The const declaration creates a read-only reference to a value. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned.

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Anthony
  • 13,434
  • 14
  • 60
  • 80
  • 28
    That's a bit misleading though. For numbers, strings, boolean, etc. (primitives) `const` is immutable. For objects and arrays it can't be reassigned, but the contents can be changed (e.g. array.push). – Florian Wendelborn Jan 02 '17 at 05:00
  • 2
    JS primitives are always immutable though. Whether you use `const` or not doesn't affect that. – 12Me21 Jun 15 '18 at 12:54
  • 1
    @Dodekeract therefore it is not immutable by definition. If the values can change it is not immutable, though it functions as immutable for the primitives you've listed – Anthony Jul 01 '19 at 20:46
  • A `const` variable most certainly is immutable. The question isn't whether `const` confers immutability, it's *to what* does `const` confer immutability? If the variable holds a reference to an object, *that reference* is immutable. The mutability of the object the variable references is an entirely separate matter. – snarf Sep 06 '20 at 20:43
17

var: Declare a variable. Value initialization is optional.

let: Declare a local variable with block scope.

const: Declare a read-only named constant.

Example:

var a;
a = 1;
a = 2; // Reinitialize possible
var a = 3; // Re-declare
console.log(a); // 3

let b;
b = 5;
b = 6; // Reinitialise possible
// let b = 7; // Redeclare not possible
console.log(b);

// const c;
// c = 9;    // Initialization and declaration at the same place
const c = 9;
// const c = 9; // Redeclare and initialization is not possible
console.log(c); // 9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Srikrushna
  • 4,366
  • 2
  • 39
  • 46
11

You have great answers, but let's keep it simple.

const should be used when you have a defined constant (read as: it won't change during your program execution).

For example:

const pi = 3.1415926535

If you think that it is something that may be changed on later execution then use a var.

The practical difference, based on the example, is that with const you will always assume that pi will be 3.14[...], it's a fact.

If you define it as a var, it might be 3.14[...] or not.

For a more technical answer, Tibos' is academically right.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Edgar Griñant
  • 599
  • 1
  • 12
  • 27
7

In my experience, I use const when I want to set something I may want to change later without having to hunt through the code looking for bits that have been hard coded, e.g., a file path or server name.

The error in your testing is another thing though. You are trying to make another variable called x, and this would be a more accurate test:

const x = 'const';
x = 'not-const';
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Melbz
  • 512
  • 4
  • 14
  • 11
    I get what you mean, but -- it's funny that "constant" for you means "thing I might want to change". : P – Venryx Apr 24 '17 at 17:16
4

Personal preference really. You could use const when, as you say, it will not be re-assigned and is constant. For example if you wanted to assign your birthday. Your birthday never changes so you could use it as a constant. But your age does change so that could be a variable.

Cjmarkham
  • 9,484
  • 5
  • 48
  • 81
4

Summary:

const creates an immutable binding, meaning a const variable identifier is not reassignable.

const a = "value1";

You cannot reassign it with

a = "value2";

However, if the const identifier holds an object or an array, the value of it can be changed as far as we are not reassigning it.

const x = { a: 1 }

x.a = 2; // Is possible and allowed

const numbers = [1, 2];
numbers.push(3); // Is possible and allowed

Please note that const is a block-scoped just like let which is not same as var (which is function-scoped).

In short, when something is not likely to change through reassignment use const, else use let or var, depending on the scope you would like to have.

It's much easier to reason about the code when it is dead obvious what can be changed through reassignment and what can't be. Changing a const to a let is dead simple. And going const by default makes you think twice before doing so. And this is in many cases a good thing.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tejas Patel
  • 1,289
  • 13
  • 25
3

The main point is that how to decide which one identifier should be used during development.

In JavaScript here are three identifiers.

  1. var (Can redeclared and reinitialize)
  2. const (Can't redeclared and reinitialize, and can update array values by using push)
  3. let (can reinitialize, but can't redeclare)

'var': At the time of coding when we talk about code standards, then we usually use the name of an identifier which is one that is easy to understand by other users and developers.

For example, if we are working thought many functions where we use some input and process this and return some result, like:

Example of variable use

function firstFunction(input1, input2)
{
    var process = input1 + 2;
    var result = process - input2;
    return result;
}


function otherFunction(input1, input2)
{
    var process = input1 + 8;
    var result = process * input2;
    return result;
}

In above examples both functions producing different-2 results, but using same name of variables. Here we can see 'process' & 'result' both are used as variables and they should be.

Example of constant with variable

const tax = 10;
const pi = 3.1415926535;

function firstFunction(input1, input2)
{
    var process = input1 + 2;
    var result = process - input2;
    result = (result * tax)/100;
    return result;
}


function otherFunction(input1, input2)
{
    var process = input1 + 8;
    var result = process * input2 * pi;
    return result;
}

Before using 'let' in JavaScript we have to add ‘use strict’ on the top of the JavaScript file

Example of let with constant & variable

const tax = 10;
const pi = 3.1415926535;
let trackExecution = '';

function firstFunction(input1, input2)
{
    trackExecution += 'On firstFunction';
    var process = input1 + 2;
    var result = process - input2;
    result = (result * tax)/100;
    return result;
}


function otherFunction(input1, input2)
{
    trackExecution += 'On otherFunction'; # Can add current time
    var process = input1 + 8;
    var result = process * input2 * pi;
    return result;
}

firstFunction();
otherFunction();
console.log(trackExecution);

In above example you can track which one function executed when & which one function not used during specific action.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vinod
  • 2,850
  • 1
  • 18
  • 23
3

The semantics of var and let

var and let are a statement to the machine and to other programmers:

I intend that the value of this assignment change over the course of execution. Do not rely on the eventual value of this assignment.

Implications of using var and let

var and let force other programmers to read all the intervening code from the declaration to the eventual use, and reason about the value of the assignment at that point in the program's execution.

They weaken machine reasoning for ESLint and other language services to correctly detect mistyped variable names in later assignments and scope reuse of outer scope variable names where the inner scope forgets to declare.

They also cause runtimes to run many iterations over all codepaths to detect that they are actually, in fact, constants, before they can optimise them. Although this is less of a problem than bug detection and developer comprehensibility.

When to use const

If the value of the reference does not change over the course of execution, the correct syntax to express the programmer's intent is const. For objects, changing the value of the reference means pointing to another object, as the reference is immutable, but the object is not.

"const" objects

For object references, the pointer cannot be changed to another object, but the object that is created and assigned to a const declaration is mutable. You can add or remove items from a const referenced array, and mutate property keys on a const referenced object.

To achieve immutable objects (which again, make your code easier to reason about for humans and machines), you can Object.freeze the object at declaration/assignment/creation, like this:

const Options = Object.freeze(['YES', 'NO'])

Object.freeze does have an impact on performance, but your code is probably slow for other reasons. You want to profile it.

You can also encapsulate the mutable object in a state machine and return deep copies as values (this is how Redux and React state work). See Avoiding mutable global state in Browser JS for an example of how to build this from first principles.

When var and let are a good match

let and var represent mutable state. They should, in my opinion, only be used to model actual mutable state. Things like "is the connection alive?".

These are best encapsulated in testable state machines that expose constant values that represent "the current state of the connection", which is a constant at any point in time, and what the rest of your code is actually interested in.

Programming is already hard enough with composing side-effects and transforming data. Turning every function into an untestable state machine by creating mutable state with variables just piles on the complexity.

For a more nuanced explanation, see Shun the Mutant - The case for const.

Josh Wulf
  • 4,727
  • 2
  • 20
  • 34
2

It provides:

  1. a constant reference, e.g., const x = [] - the array can be modified, but x can't point to another array; and

  2. block scoping.

const and let will together replace var in ECMAScript 6/2015. See discussion at JavaScript ES6 Variable Declarations with let and const

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Genovo
  • 551
  • 6
  • 6
  • The subject of [this meta question](https://meta.stackoverflow.com/questions/405497/final-answer-rendering-is-different-in-the-editor-preview). – Peter Mortensen Feb 27 '21 at 04:38
2

First, three useful things about const (other than the scope improvements it shares with let):

  • It documents for people reading the code later that the value must not change.
  • It prevents you (or anyone coming after you) from changing the value unless they go back and change the declaration intentionally.
  • It might save the JavaScript engine some analysis in terms of optimization. E.g., you've declared that the value cannot change, so the engine doesn't have to do work to figure out whether the value changes so it can decide whether to optimize based on the value not changing.

Your questions:

When is it appropriate to use const in place of var?

You can do it any time you're declaring a variable whose value never changes. Whether you consider that appropriate is entirely down to your preference / your team's preference.

Should it be used every time a variable which is not going to be re-assigned is declared?

That's up to you / your team.

Does it actually make any difference if var is used in place ofconst` or vice-versa?

Yes:

  • var and const have different scope rules. (You might have wanted to compare with let rather than var.) Specifically: const and let are block-scoped and, when used at global scope, don't create properties on the global object (even though they do create globals). var has either global scope (when used at global scope) or function scope (even if used in a block), and when used at global scope, creates a property on the global object.
  • See my "three useful things" above, they all apply to this question.
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

When it comes to the decision between let and const (both block scoped), always prefer const so that the usage is clear in the code. That way, if you try to redeclare the variable, you'll get an error. If there's no other choice but redeclare it, just switch for let. Note that, as Anthony says, the const values aren't immutable (for instances, a const object can have properties mutated).

When it comes to var, since ES6 is out, I never used it in production code and can't think of a use case for it. One point that might consider one to use it is JavaScript hoisting - while let and const are not hoisted, var declaration is. Yet, beware that variables declared with var have a function scope, not a block scope («if declared outside any function, they will be globally available throughout the program; if declared within a function, they are only available within the function itself», in HackerRank - Variable Declaration Keywords). You can think of let as the block scoped version of var.

marcolz
  • 2,880
  • 2
  • 23
  • 28
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
0

'const' is an indication to your code that the identifier will not be reassigned.

This is a good article about when to use 'const', 'let' or 'var': JavaScript ES6+: var, let, or const?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ananda
  • 477
  • 5
  • 8
0

I am not an expert in the JavaScript compiling business, but it makes sense to say, that V8 makes use of the const flag.

Normally after declaring and changing a bunch of variables, the memory gets fragmented, and V8 is stopping to execute, makes a pause some time of a few seconds, to make garbage collection, or garbage collection.

If a variable is declared with const, V8 can be confident to put it in a tightly fixed-size container between other const variables, since it will never change.

It can also save the proper operations for that datatypes since the type will not change.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sam Washington
  • 626
  • 4
  • 12
-1

My opinions:

Q. When is it appropriate to use const in place of var?
A. Never!

Q: Should it be used every time a variable which is not going to be re-assigned is declared?
A: Never! Like this is going to make a dent in resource consumption...

Q. Does it actually make any difference if var is used in place of const or vice-versa?
A: Yes! Using var is the way to go! Much easier in dev tools and save from creating a new file(s) for testing. (var in not in place of const - const is trying to take var's place...)

Extra A: Same goes for let. JavaScript is a loose language - why constrict it?!?

iAmOren
  • 2,760
  • 2
  • 11
  • 23