[comment]: # "markdown: { smartypants: true }" # `const`, `let`, `var`
in JavaScript
AJ ONeal
[@\_beyondcode](https://twitter.com/@_beyondcode)
[twitch.tv/coolaj86](https://twitch.tv/coolaj86)
(that was alphabetical order)
# `var`, `const`, `let`
# `var`, `const`, `let` (that's the order in which we'll discuss them)
# I'm AJ ONeal (and I hate `const`)
# `var`
# `var` - is _incredibly_ simple.
# `var` - is _incredibly_ simple. - has _exactly_ ONE rule
> Variables declared with **`var`** are scoped to the **_whole_ function** that > contains them, **recursively**.
And _exactly_ NO exceptions.
And _exactly_ NO exceptions. Period.
Example: Flat `var`s: ```js [1-11|2,8] function foo() { var answer = 42; // ... } function bar() { var random = 4; // ... } ```
Example: Nested `var`s: ```js [1-11|1-2|1-2,4-5] function foo() { var answer = 42; function bar() { var random = 4; // ... } // ... } ```
Trick Question #1:
Trick Question #1: What's the scope of **`awkward`**?
Trick Question #1: What's the scope of **`awkward`**? ```js [10|1,4] function foo() { var answer = 42; function bar() { var random = 4; // ... } var awkward = -0; // ... } ```
Scope starts at the **function declaration**.
Scope starts at the **function declaration**. And is scoped to the _whole_ function.
Scope starts at the **function declaration**. And is scoped to the _whole_ function. Recursively.
```js [1,4,7] function foo() { var answer = 42; function bar() { var random = 4; function baz() { var deep = 3; // ... } // ... } // ... } ```
Trick Question #2
Trick Question #2 How many scopes are there?
Trick Question #2 How many scopes are there? ```js [1-13|2,4,5,10] function foo() { var answer = 42; for (var i = 0; i < 10; i += 1) { var silly = i; // ... } var awkward = -0; // ... } ```
## 1
## 1 - One `function`.
## 1 - One `function`. - One scope.
All **`var`** have **_whole-function_** scope.
Trick Question #3:
Trick Question #3: What's the scope of **`nofunc`**?
Trick Question #3: What's the scope of **`nofunc`**? ```js [1] var nofunc = Infinity; function foo() { var answer = 42; function bar() { var random = 4; // ... } // ... } ```
# None
# None - No `function`.
# None - No `function`. - No scope.
# None - No `function`. - No scope.
(it's **_global_**)
### `var` Conclusion:
### `var` Conclusion: `var` is _different_...
### `var` Conclusion: `var` is _different_... but not _bad_.
# `const`
# `const` ... is tarded
### Part A: Appropriation
### Part A: Appropriation (what's **STUPID**...)
```js const PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; ``` (what a `const` _should_ look like)
>
"The `const` keyword declares the following item as constant. Constant > items can be completely computed at compile time, and any code that refers to > them is replaced with the constant's computed value during compilation. > > A constant has no memory or other storage associated with it (it is not a > place). You can think of constant as a convenient name for a particular > value."
"Rust for Rustaceans" by Jon Gjengset
Recap
Recap - `const` means `constant`.
Recap - `const` means `constant`. - _constants_ can be computed at _compile_ time.
Recap - `const` means `constant`. - _constants_ can be computed at _compile_ time. - the value of a _constant_ doesn't change.
And conventionally...
And conventionally... ```js const PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; ```
And conventionally... ```js const PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062; ``` a `const` is `ALL_CAPS`
... but not in EcmaScript.
```js function greet(name) { // variable! const greeting = `Hello ${name}!`; // ... } ```
```js function greet(name) { // variable! const greeting = `Hello ${name}!`; // ... } ``` Can't be computed ahead-of-time? NOT a constant!
```js const items = []; // mutable! items.push(1); ```
```js const items = []; // mutable! items.push(1); ``` Can be mutated... at all? NOT a constant!
An immutable reference is no more a `const`...
An immutable reference is no more a `const`... than acne is a cancer.
But...
But... but...
But... but... but...
```js const answer = 42; // throws an error! // See! It's an immutable reference!! answer += 1; ```
```js const answer = 42; // throws an error! // See! It's an immutable reference!! answer += 1; ``` Not a _constant_!
## Part B: Just Moral Cause
## Part B: Just Moral Cause (what's **_WORSE_**...)
Readable conditional assignment:
Readable conditional assignment: ```js function greet(name) { var foo; if (name) { foo = "Hey ${name}!"; } else { foo = "Welcome!"; } // ... } ```
With `const` brain drain:
With `const` brain drain: ```js function greet(name) { const foo = name ? "Hey ${name}!" : "Welcome!"; // ... } ```
With `const` brain drain: ```js function greet(name) { const foo = name ? "Welcome!" : "Hey ${name}!"; // ... } ``` 😈
Anyway...
I don't know about you but...
Forgetting if I want to change a variable
_isn't_ a problem I have.
I don't know about you but...
Forgetting if I want to change a variable
_isn't_ a problem I have.
(at least not in _that_ way but... more on that later)
# `let`
# `let` (Schrodinger's **`var`**)
`let` is **_supposed_** to declare variables
`let` is **_supposed_** to declare variables in block scope
`let` is **_supposed_** to declare variables in block scope ```js { { { let awkward = -0; } } } ```
er... **_whole_** block scope... ```js [3-4,7,10-13] function foo() { for (let i = 0; i < 10; i += 1) { let silly = i; // ... } { { let awkward = -0; } let superAwkward = -0; } // ... } ```
And that _mostly_ works...
And that _mostly_ works... but is only _necessary_ for anti-patterns
And that _mostly_ works... but is only _necessary_ for anti-patterns (meaning really long functions)
And `let` _breaks_ `switch`:
```js [3,7] switch (name) { case "foo": let answer = 42; // ... break; case "bar": let answer = 4; // ... break; // ... } ```
```js [3,7] switch (name) { case "foo": let answer = 42; // ... break; case "bar": let answer = 4; // ... break; // ... } ``` (Schrodinger's **`var`**)
```js [7] switch (name) { case "foo": let answer = 42; // ... break; case "bar": answer = 4; // ... break; // ... } ```
```js [3-6,9-12] switch (name) { case "foo": { let answer = 42; // ... } break; case "bar": { let answer = 4; // ... } break; // ... } ```
But...
But... `let` does allow you to write confusing, otherwise buggy code:
But... `let` does allow you to write confusing, otherwise buggy code: ```js function confusing() { for (let count = 0; count < 10; count += 10) { setTimeout(function () { // count increments as... expected? console.log(count); }, 1000); } } ```
# 🤷♀️
# Missed Opportunities
Problems that I _do_ have that `const` and `let` still don't solve:
# Shadowing
`let` doesn't enable _intentional_ shadowing:
`let` doesn't enable _intentional_ shadowing: ```js function foo() { let answer = "42"; let answer = parseInt(answer, 10); // ... } ```
of any sort... ```js function foo() { let answer = "42"; function bar() { let answer = parseInt(answer, 10); // ... } // ... } ```
and `const` doesn't prevent _unintentional_ shadowing:
and `const` doesn't prevent _unintentional_ shadowing: ```js function foo() { const name = "foo"; function bar() { const name = "bar"; // ... } // ... } ```
`try` / `catch` is still broken:
`try` / `catch` is still broken: ```js let name; try { name = "foo"; throw new Error("oops"); } catch (e) { // nothing is undone // (the stack is not unwound) } // name is still "foo"! ```
# 🤷♂️
## Conclusion
## Conclusion - _Fails_ to make EcmaScript like other languages
## Conclusion - _Fails_ to make EcmaScript like other languages - Doesn't _fix_ JavaScript's bugs
## Conclusion - _Fails_ to make EcmaScript like other languages - Doesn't _fix_ JavaScript's bugs - Adds _more_ bugs to EcmaScript
## Conclusion - _Fails_ to make EcmaScript like other languages - Doesn't _fix_ JavaScript's bugs - Adds _more_ bugs to EcmaScript Therefore...
## Conclusion - _Fails_ to make EcmaScript like other languages - Doesn't _fix_ JavaScript's bugs - Adds _more_ bugs to EcmaScript Therefore... # BAD IDEA!
# FIN
- Like - Sub - Follow - Click all-the-things