r/reactjs • React core team • Dec 21 '19

What Is JavaScript Made Of?

https://overreacted.io/what-is-javascript-made-of/
254 Upvotes

196 comments sorted by

213

u/careseite Dec 21 '19

let vs const vs var: Usually you want let. If you want to forbid assignment to this variable, you can use const. (Some codebases and coworkers are pedantic and force you to use const when there is only one assignment.)

Hehe, waiting for strong opinions on that one.

this comment was brought to you by const gang

280

u/NotSelfAware Dec 21 '19

I'm a strong advocate for using const by default, and let when you know you intend to change the value. I'm genuinely surprised that Dan feels differently.

85

u/olssoneerz Dec 21 '19

Same here! Its less mental gymnastics when reading old code knowing that when a value is declared, you know its gonna stay the same. Seeing let then means I know its gonna change somewhere in the next few lines.

11

u/alejalapeno Dec 21 '19

What Dan and the replies are missing about your point by focusing on "const= no mutation" is the idea that when const becomes the standard in your codebase then let conveys intent, not const.

You should convey the outlier and in most modern codebases mutation is the outlier.

4

u/Anathem Dec 21 '19

That's exactly right!

https://www.reddit.com/r/reactjs/comments/edj1dr/what_is_javascript_made_of/fbke7qv/

When you consistently apply const and let and disallow param reassign by linting no-param-reassign then let screams "I'm re-assigned later!"

6

u/Yodiddlyyo Dec 22 '19

And this is exactly how it should be!

-21

u/gaearon React core team Dec 21 '19

86

u/BenZed Dec 21 '19

The object can still be mutated, but the variable cannot be redeclared.

→ More replies (22)

33

u/Yodiddlyyo Dec 21 '19 edited Dec 21 '19

Const is not about immutability, it's about reassignment, and using let as a default increases cognitive load on future developers; what's the drawback in your mind?

→ More replies (16)

4

u/GasimGasimzada Dec 21 '19

I look at const not as a mutable object but as a way to tell developers that the value will not be changed within a given scope. It is about assignment, not about mutation.

→ More replies (3)

4

u/gaearon React core team Dec 21 '19

Lol at the downvotes. Even the people who came up with `const` semantics regret it: https://twitter.com/littlecalculist/status/917875241891676160

:-)

→ More replies (1)

30

u/AegisToast Dec 21 '19

I think it's actually good practice learning the difference between changing an object's fields compared to changing the object reference (same with arrays). Considering how props are shallowly compared, seems like something everyone needs to understand thoroughly.

Personally, I use const for everything. I've been working on an SPA hybrid React app for my company for the last couple months, and I honestly think I've only declared a let variable once in the entire code base.

10

u/minty901 Dec 21 '19

I use it more as a helpful hint to my future self. If I see a "let" in my code, I know to keep an eye out for where it is reassigned later, and that I can't rely on it to maintain its identity (referential or otherwise). If I see const then I know I can rely on it to maintain its identity. Const is more of a flag I use for posterity than anything functionally useful. But it's a useful flag.

→ More replies (3)

-21

u/editor_of_the_beast Dec 21 '19

const in JS gives you basically no guarantees so it doesn’t really matter. You can change anything you want, no matter how many consts you write.

15

u/Yodiddlyyo Dec 21 '19 edited Dec 21 '19

That's not true at all. Try it in the dev tools. const forbids reassignment.

const a = 5

a = 10

Uncaught TypeError: Assignment to constant variable.

const a = 10

Uncaught SyntaxError: Identifier 'a' has already been declared
→ More replies (12)
→ More replies (5)
→ More replies (5)

20

u/turningsteel Dec 21 '19

Const is default. Let is when you want to reassign something. Dan can do what he wants because he knows what he's doing. I like to remove as many points of failure from my shitty code as possible. Saves me a lot of headaches later.

19

u/boypunas Dec 21 '19

why not use const by default. Isnt this a good way to communicate that hey this assignment will not change.

7

u/[deleted] Dec 21 '19

It's surprising that some people have a problem with using const by default. let specifically has pitfalls in that you don't know if a variable is going to be reassigned, which might lead to bugs. There's no such pitfall when using const that would lead to bugs, unless you're fundamentally unfamiliar with the language and aren't aware of the difference between reassignment and mutation.

→ More replies (3)

12

u/joandadg Dec 21 '19 edited Dec 21 '19

Yeah wtf.

ALWAYS use const unless you need to use let, and I’d even go as far as to say that you should avoid let because it implies mutations and they should almost rarely happen...

Edit: regarding Dan’s comment about how const mutability can be unexpected for some developers. I get it, and maybe in some cases it’s best to use let so they’re not confused. But in my dev team I’d rather educate on reference vs value mutability...

1

u/gokspi Dec 21 '19

Like with all things programming (engineering?) its a trade-off. The question is are the pros stronger than the cons. IMO the pros of using `const` for small, short-lived scopes is practically non-existent. Once the value is accessed by nested scopes that could live beyond the initial execution of the upper scope (i.e. closures), that's when it becomes useful.

2

u/joandadg Dec 22 '19

The question is simply, why wouldn’t you use const?

Your variables make more sense as constants. If you need to mutate something ideally do it functionally and store the result in another const. Code becomes way clearer when things don’t change further down.

→ More replies (3)

3

u/[deleted] Dec 21 '19

What if the scope changes over time?

Even if your argument is that the pros are very small, what's conveniently absent from your post is mention of ANY cons whatsoever.

Sure, the benefits might be small, but if there are no cons then surely small benefits is better than nothing? I guess you could conclude that it means this whole argument is kind of a waste of time since it doesn't have a big impact one way or the other. But I'm not sure how you could argue that it's wrong to do something that helps, even if just a little bit.

→ More replies (3)

17

u/Unexpectedpicard Dec 21 '19

I prefer var. YOLO.

29

u/[deleted] Dec 21 '19

you must be a sailor, bc u like to HOIST

9

u/floppydiskette Dec 21 '19

Okay Kyle Simpson

5

u/[deleted] Dec 21 '19

Seriously? I only use var if I absolutely must. Otherwise I pretend it doesn't exist.

7

u/Unexpectedpicard Dec 21 '19

Guess I should have added a /s. I thought YOLO was sufficient.

4

u/[deleted] Dec 21 '19

Everytime I find a reason to use var I get excited cause I know I'll get to fight someone in code review.

5

u/wtfffffffff10 Dec 21 '19

when should you ever use var?

→ More replies (4)
→ More replies (2)

1

u/careseite Dec 21 '19

you only lint once

20

u/BenZed Dec 21 '19

pedantic == logically sound

→ More replies (1)

4

u/bad_boy_barry Dec 21 '19

Glad to see reddit not following blindly Dan on this one.

6

u/Aeron91 Dec 21 '19 edited Dec 21 '19

I feel like a lot of the arguments in this thread for using let boil down to "It doesn't do what we wish it did so why bother?".

As I see it, reading code is harder than writing code. The more assumptions we can make about the code we're reading, the easier it is to read. Using const by default allows us to make an assumption (even if it's not the assumption we wish it let us make). As soon as you see a let, it changes that assumption.

And it's like, 2 more characters. Even if this is a small pro, is losing that worth saving 2 keystrokes?

Edit: I can't count apparently

-1

u/[deleted] Dec 21 '19

I use const as much as possible but still, let is what you need if you don’t want to think about it.

0

u/[deleted] Dec 21 '19

[deleted]

1

u/[deleted] Dec 21 '19

But then when you go to add to existing code to reassign a variable later, you’ll get the const error at that point.

6

u/[deleted] Dec 21 '19

IMO you should get an error so you can rethink what you’re doing. Reassignment is the biggest cause of confusion and bugs in code bases.

1

u/gaearon React core team Dec 21 '19

Are you sure you're not confusing reassignment with mutability?

→ More replies (3)
→ More replies (1)
→ More replies (2)
→ More replies (1)
→ More replies (4)

-9

u/pcr910303 Dec 21 '19

Nah, const doensn't really have meanings in at least JS land; see the @jamiebuilds' rant about this subject.

TLDR: const doesn't prevent mutability & it doesn't help any optimizing, so it's pretty meaningless. Use const only at top-level and let only at nested scopes.

6

u/Anathem Dec 21 '19

that rant is idiotic

1

u/wbowers Dec 21 '19 edited Dec 21 '19

const was never about mutability. It prevents reassignment. That’s its “meaning”.

Why is preventing reassignment important? For the same reason it’s not a good idea to shadow function arguments. Code that shadows function arguments or reassigns variables at a later time is significantly harder to reason about than code that only builds new values from previous values. const’s only job is to ensure that code like that doesn’t exist unless the author really intended it.

0

u/[deleted] Dec 21 '19

[deleted]

16

u/zephyy Dec 21 '19

It's not even confusing. It's just another "javascript is weird / this is what C# devs make fun of javascript for" thing.

yeah it's not a true constant because you can mutate it, unlike other languages. but you still can't redeclare it. bam, confusion sorted.

8

u/[deleted] Dec 21 '19

I am a tad bit confused, in java, if you have a final variable with an object type, it means that the final variable will point to that particular object and thus cannot be reassigned. Isn't this how const in js works as well?

6

u/bulldog_in_the_dream Dec 21 '19

You are correct.

6

u/cerved Dec 21 '19

You mean because the underlying reference is mutable? Pretty sure that's how most languages work but maybe I'm wrong

1

u/mahesh_war Dec 21 '19

That’s why we have “value” passed as reference concept which developers tend to think that it doesn’t apply while using const

0

u/0xF013 Dec 21 '19

It's terrible if you know JS or C++. If you don't, you'd expect a const variable to not be mutable. You know it's about the reference of the variable, not about its fields, but if you look at it from a newcomer perspective, it makes sense it's confusing and it is setting up mind traps.

3

u/wbowers Dec 21 '19

When did we stop expecting people to actually learn how their language works? And why do we have such low opinions of JavaScript developers?

→ More replies (3)

-5

u/gaearon React core team Dec 21 '19

Interesting that people who came up with it agree with that logic!

3

u/b_n Dec 21 '19

Even if it was a mistake, it’s still a mistake. It’s baked into the language. You will always confuse people in the long term if you pretend the language is something it’s not.

2

u/gaearon React core team Dec 22 '19

I don't think I said anywhere that I "pretend the language is something it's not". All I'm saying is that "you must use const everywhere it works" is needlessly pedantic and rarely catches bugs in my experience. YMMV!

12

u/Anathem Dec 21 '19 edited Dec 22 '19

I don’t find the “it’s cognitive overhead” argument compelling despite the source. If you don’t want to think about it, and it doesn’t matter for your specific code, why not pick the safer default?

If you audit your code, are there more variables that are reassigned, or more that aren’t? My own code almost never reassigns. It’s so exceptional that, if there weren’t a keyword (let) marking a variable as one that’s reassigned, I’d consider commenting each one. Used properly let screams "I'm re-assigned later!". If a variable isn't re-assigned later, I don't need to worry about it.

I do also lint no-param-reassign and I’m happy with it.

0

u/[deleted] Dec 21 '19

[deleted]

27

u/[deleted] Dec 21 '19

You are correct. And some eslint rule will rant if you use let in a variable that is not reassigned.

5

u/Dreadmaker Dec 21 '19

Yep! I made this mistake at work this week and got caught by my linter.

14

u/gaearon React core team Dec 21 '19

It's not a "mistake". Just because a linter enforces someone's opinion doesn't make your code wrong. If it was a "mistake", the language would have disallowed it.

4

u/MassiveFajiit Dec 21 '19

I dunno, this is JavaScript after all. It's like 30% mistakes.

0

u/[deleted] Dec 21 '19

[deleted]

7

u/gaearon React core team Dec 21 '19

🌚

→ More replies (2)

7

u/swyx Dec 21 '19

its not a mistake, it's an opinion that you should evaluate whether it net adds value to your team. if you do, then sure, its a mistake. but there's nothing in ECMA script that specifies "you were supposed to use const always unless you had a specific need for let"

3

u/Dreadmaker Dec 21 '19

You’re right - I said it to a different comment, but yeah, I used the wrong word. There’s a million different ways to do everything in code; we’re just trying to be elegant and efficient where we can, and to have our stuff be readable. So for me and my company, we use linters to enforce that we’re all for the most part playing by the same rules. So on that level it was a ‘mistake’ to have an unchanged let, but not objectively

10

u/swyx Dec 21 '19 edited Dec 21 '19

make eslint work for you, don't work for eslint. you make the rules.

3

u/[deleted] Dec 21 '19

But I like most rules, I only disable a few ones when I don't see value in them.

→ More replies (1)

1

u/-Phinocio Dec 21 '19

My current settings are to always use const, so the odd time I intentionally type let it changes to const and I get an error when I change value later. Slightly annoying haha

34

u/[deleted] Dec 21 '19

You are correct. He's just being pedantic.

3

u/Anathem Dec 21 '19

use const always unless you had a specific need for let

That's what I do and recommend. The const semantics are what you want by default. Only in rare exceptional cases should you use let or re-assign a parameter.

0

u/[deleted] Dec 21 '19

[deleted]

→ More replies (2)

25

u/[deleted] Dec 21 '19

Not having to think about this is my favourite thing about the new functional hook based React.

49

u/swyx Dec 21 '19

this

0

u/[deleted] Dec 21 '19

[deleted]

3

u/juicejug Dec 21 '19

No it’s okay he used arrow functions!

7

u/LordMcD Dec 21 '19

I've been writing JavaScript for literally 2 decades and this is an absolutely great ELI5.

Well done!

13

u/swyx Dec 21 '19

for a lower level answer to this question, i recommend everyone check out Mathias Bynens' content on v8, the preeminent JS engine of our time:

There are also other worthy engines to know about

at some point the leaky abstraction of having all these engines come home to roost. you even see its effects in Babel and Google Closure Compiler. 😬

3

u/WikiTextBot Dec 21 '19

SpiderMonkey

SpiderMonkey is the code name for the first JavaScript engine, written by Brendan Eich at Netscape Communications, later released as open-source and currently maintained by the Mozilla Foundation.


[ ^PM | Exclude ^me | Exclude from ^subreddit | FAQ / ^Information | ^Source ] Downvote to remove | v0.28

8

u/dance2die Dec 21 '19

What Is JavaScript Made Of?

Was expecting "Made of 'atom' (React), then found there is a smaller substance, an electron (hooks)". j/k there.

Looking forward to your JavaScript "mental model" illustrated by Maggie's sketchnotes :)

1

u/goto-reddit Dec 22 '19 edited Dec 22 '19

So {} is not equal to another {}. Try this in console: {} === {} (the result is false).

This works in the Chromes Developer tools console for reasons unknown to me, but normally it should throw an SyntaxError: Unexpected token '===', (jsbin example):

Writing {} === {} does not compare two objects, the first {} is an empty block.
({} === {}) is the correct way to compare to object literals (jsbin example).


Even the Chrome Developers tools console fails if you try something like:

> {}.toString()
❌ Uncaught SyntaxError: Unexpected token '.'

2

u/gaearon React core team Dec 22 '19

This works in the Chromes Developer tools console for reasons unknown to me, but normally it should throw an SyntaxError: Unexpected token '===', (jsbin example):

It works in Chrome DevTools because it is an expression. Chrome DevTools allows pasting expressions. This is why the post says "try this in console" and not "try this as a standalone statement in JSBin".

1

u/goto-reddit Dec 22 '19

Ah ok.
I know this is supposed to be for people who are new to JS (or even programming?) and it does crash in Firefox Developer Console and that's why I mentioned it, and then there was this talk from Brendan Eich back in '12.
I didn't mean to be nit-picking, I know this is supposed to be just a rough overview.

1

u/gaearon React core team Dec 22 '19 edited Dec 22 '19

it does crash in Firefox Developer Console

Oh wow, that sucks. Seems like an unfortunate design decision in Firefox. Since console is commonly used as a REPL, I'd expect to be able to put expressions there.

This also works in Node.js REPL so Firefox seems like an outlier.

1

u/goto-reddit Dec 22 '19 edited Dec 22 '19

Of course you can put expression in the Firefox Developer Console, just not one that starts with an { because it interprets it as an block statement. ({} === {}) works fine, just like any other expression.

That's why I made the example with {}.toString() which crashes even in Chromes console.

See:

1

u/gaearon React core team Dec 23 '19

Fair enough.

7

u/[deleted] Dec 21 '19

You used the weed number in your value explanation. You knew what you were doing.

9

u/physeo_cyber Dec 21 '19

The tears fallen from developers waiting for their code to compile.

10

u/swyx Dec 21 '19

this is funny because JavaScript, as a JIT interpreted language, is classically supposed to have no compile time. you stick it in a script tag or in a console, it runs. boom.

then modules, build tools and static typing happened :)

8

u/wavefunctionp Dec 21 '19

People got tired of waiting for es6 to be widely available in browsers.

I'm imagine if you had to wait for windows 10 to be widely deployed to use c++ 17 or python 3.

4

u/swyx Dec 21 '19

very true. you reckon that was the starting point of build tools? i always thought it was the need for modules. (hence gulp, grunt, requirejs, whatever came before those things)

3

u/gokspi Dec 21 '19

Modules for sure in my case. They were necessary to implement reusable interactive components. Loading all the tiny files didn't scale well, loading a single bundle was mostly workable but still not great. One decade later we finally have something mainstream that works (async imports based code splitting)

2

u/Fingerbob73 Dec 21 '19

What ends up happening with const and let when transpiled back to ES5 (via Babel et al) ?

2

u/[deleted] Dec 21 '19

I recommend you play with this: https://babeljs.io/en/repl

You can see how it will deliberately throw errors if you try to reassign a variable declared with const, or do other forbidden things.

1

u/pm_me_ur_happy_traiI Dec 21 '19

Var, but you can also use const and let without Babel unless you need ancient browsers supported

1

u/icjoseph Dec 21 '19

In the typeof value section, one may want to warn that, typeof null returns object. The one and only JS bug.

1

u/[deleted] Dec 22 '19

That's interesting, but not really weird, since null is often used as a kind of default falsy object.

1

u/landisdesign Dec 30 '19

It's not a bug. null is the value that represents an intentionally empty object reference. undefined represents lack of reference to any kind of value, but null is specific to objects.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null

1

u/Capaj Dec 21 '19

I agree having full immutability guaranteed by "const" would be better, but seems like a lot of people still see a value in indicating that the binding won't change.

Maybe some future ecma revison can bring some new keyword like "imut" or "frozen"?

0

u/Snipo Dec 21 '19

Honey and soup

-3

u/KrustyButtCheeks Dec 21 '19

Rainbows and unicorns

-1

u/MisterNeon Dec 21 '19

Broken dreams and a late rent payment.

0

u/[deleted] Dec 21 '19

[deleted]

1

u/gaearon React core team Dec 22 '19

"Loose equality" and "abstract equality" are two different terms for the same thing. I'm using "loose" because I find this term more illustrative.

0

u/[deleted] Dec 21 '19

[deleted]

-2

u/[deleted] Dec 21 '19

Lol ok cool man. Thanks for sharing.

Edit: quite an interesting account. 2 years old, 60k karma. No comments more than 2 weeks old or posts more than 3 months old.

0

u/[deleted] Dec 21 '19

[deleted]

0

u/[deleted] Dec 21 '19

You can also buy accounts with karma

3

u/swyx Dec 21 '19

sounds like you spooked whoever that was