9

Disclaimer: I know that the question below might be seen as "asking for opinions" (so it'd be off-topic).
But it's not the case: I'm looking for pros and/or cons facts which should be took in account while thinking about that.

By chance I just read (from the excellent Exploring ES6) an excerpt focusing on const vs let vs var, where the conclusion states (bolding is mine):

Then we have two approaches:

  1. Prefer const: const marks immutable bindings.
  2. Prefer let: const marks immutable values.

I lean slightly in favor of #1, but #2 is fine, too.

What puzzles me is: this preference seems to be based on the deep technical significance of the resulting difference betweeen the two approaches, as if the author feels essentially concerned by how the code works at low level.

But I feel concerned also (and maybe first!) by the readability aspect: from this point of view, #2 seems better to make the code more semantically significant about what happens to the processed data.

But maybe I'm missing some advantages of the #1 choice...?


EDIT, taking advantage of the link proposed as duplicate: Why most of the time should I use const instead of let in javascript?

In fact the accepted answer to that question actually exposes things in such a way that it rather enforces me to my previous view, i.e. #2 is better than #1.

BTW I realized that my question was probably not as clear as it should, so here is a more detailed rewording:

  • I'm quite aware of (AFAIK) all the technical differences between const and let, so my question doesn't ask for anything about that.
  • The only point really involved by the choice between #1 and #2 lies in using const for any immutable object (though its content may be changed!) vs for frozen objects only.

It's there that I'm surprised the author prefers #1, since (from my point of view) it's rather misleading.
The most frequent way of using objects is that their content changes during the process, so reading const at its declaration level, if #1 is used:

  • at best we don't know what is supposed to happen to it.
  • at worst we may imagine that its content will never change, while it can!

In the other hand, choosing to use #2, we can trust that a const-declared object will not change (indeed apart from oversight and/or bug).

So to go back to my question: since the above reflexion seems to clearly lead to choose #2, I wonder what point I may have missed, which makes the author prefer #1.

Community
  • 1
  • 1
cFreed
  • 4,404
  • 1
  • 23
  • 33
  • This might be interesting: http://softwareengineering.stackexchange.com/questions/278652/how-much-should-i-be-using-let-vs-const-in-es6 – Fabian Lauer Dec 25 '16 at 07:38
  • @FabianLauer Thanks for this link: sure it's interesting. But I notice that it (and yet the other links it leads to) also focuses on the technical aspect (essentially regarding reliability against bugs). So I'm surprised nobody seem to be concerned by readability, while "const everywhere" totally loses semantic pertinence. – cFreed Dec 25 '16 at 09:04
  • If you always use `const` then `let` stands out and that _"seems better to make the code more semantically significant about what happens to the processed data"_. In other words: your argument works both ways. This has been discussed a million times on the web and that very argument has been used almost as often. – a better oliver Dec 26 '16 at 18:03
  • Possible duplicate of [Why most of the time should I use const instead of let in JavaScript?](http://stackoverflow.com/questions/41086633/why-most-of-the-time-should-i-use-const-instead-of-let-in-javascript) – a better oliver Dec 26 '16 at 18:04
  • @zeroflagL Thanks for your link. It helped me to clarify my question. Please look at my edited answer. – cFreed Dec 27 '16 at 17:44
  • #2 is misleading. The value of a variable is either a primitive value or a reference to an object. It's **never** an object. So when you change an object you don't change the value of the variable. The value of a variable can only be changed by assigning a new value to it. `const` prevents that. Using `const` for objects only if the are frozen doesn't make much sense. Constants and frozen objects are different concepts. – a better oliver Jan 02 '17 at 09:03
  • @zeroflagL Definitely I must realize that it's purely matter of opinion: what is misleading from your point of view is the opposite that what it is from mine! If I correctly understand you prefer the code informes you of what happens _technically, about the variables handling (the containers of the data)_, while I prefer it makes me guess what happens _semantically, about the data themselves_. Really different needs, founded of different "philosophies". Thanks for your clarification, anyway. – cFreed Jan 02 '17 at 12:14

2 Answers2

7

To keep inline with your fact-seeking journey, I'll avoid stating opinions and describe my answer in objective, simple terms.

The author's preference is not based on "deep technical significance" because the significance is actually rather shallow: in short, the only difference between the two keywords is that a const variable cannot be reassigned, but a let variable can.

The intent of preference #1 is to use const in the specific manner in which it was defined, preventing pointing a variable at a new assignment.

The intent of preference #2 is to pretend (or act) like any RHS value initializing a const variable is immutable, which requires effort on the developers' part to know that and act accordingly.

A disadvantage of #2 is that it is introducing a convention for coding with const that is inconsistent with its actual function, so it's mainly a matter of coding standards and code maintenance. In other words, if a dev team dictates that const must only be used for immutable declarations, it will make the code easier to understand that such values should not be modified, but it's actually not the case that they cannot be modified. (If this convention was to be followed, it would make sense that const only be used for values that are actually immutable, e.g., using Object.freeze().)

The advantage of #1 is that you're using const as it was designed: you're treating such variables as if their assignment cannot be changed, not pretending const offers something that it does not provide (i.e., immutability), so there's no potential for developers to mistakenly modify the contents of a const object that they are supposed to pretend cannot be modified.

Rommel Santor
  • 1,021
  • 7
  • 10
  • +1 for this answer. I totally agree with your comment about #2, though it's why I personally tend to prefer it (in my mind, establishing some kind of best practices). So it enforces the idea that it remains matter of opinion, since I don't actually notice any _objective_ strong [dis]advantage in #1 nor #2. Thanks. – cFreed Dec 26 '16 at 02:01
  • Related to this, I wrote a function called `immute()` to actually make a variable natively, deeply immutable: https://github.com/rommelsantor/immute – Rommel Santor Sep 02 '17 at 11:37
  • >so there's no potential for developers to mistakenly modify the contents of a const object that they are supposed to pretend cannot be modified. how? i can push new values to `const arr = []` right? – Baris Senyerli Sep 30 '22 at 04:35
  • 1
    @BarışŞenyerli I think you missed the point of that statement, which is that if following convention #2, it would be easy for devs to mistakenly modify that `arr` when they're supposed to pretend they can't. – Rommel Santor Oct 05 '22 at 19:25
  • @RommelSantor yeah. Right! – Baris Senyerli Oct 06 '22 at 02:04
1

So we know that var is function scope, and we know that let and const are block scope.

You can only ever assign a value to the same let & const variable once.

Say you set

let name = 'John';

and then you change the value to

let name = 'Doe';

it's not gonna let you, it will say name is already been declared but you can however update the let variable.

name = "Doe";

But you cannot declare it twice.

Unlike var

var name = 'John';
var name = 'Doe';

const value cannot be updated like let

Ex:

const API = 'acb123';

you cannot change its value later like let

API = 'azxy123';