#6

Bindings again

Variables


let x = 5

What does this do again?


let x = 5
Think of it the code this way: First, we ask JavaScript to create a name x. Then we ask if to give us the number value 5 and attach the name x to it. Thus we can refer to the value 5 later by the name x.

Because we’re using let, we can always bind the name again to another value later:


let x = 5
x = 6
To reassign the name x to 6, we must first detach x from its current value 5.
Next, we attach x to the number 6. A name is always attached to at most one value, never two.

We can’t do this with const because it creates a constant binding that cannot be changed:


const x = 5
x = 6 // TypeError: Assignment to constant variable

After declaring, we can use the name to refer to its bound value:


let x = 5
console.log(x) // 5

We can operate on the name as we would on the value:


let x = 5
console.log(x + 2) // 7

We can also bind a name to the value of another name:


let x = 5
let y = x
We declare x as 5. Then we create the name y. The right hand side of the assignment says x, so we ask for the value of x, which is 5. Next, we attach y to that value 5. x and y are now bound to the same value, 5. We see that a value may have multiple names, and a name is never attached to another name.

What if we reassign one of them?


let x = 5
let y = x
x = 6
We ask JavaScript to give us the value 6.
Then we detach x from 5 and attach it to 6. Now, x is bound to 6, but y is still bound to 5.

Reserved words

You can’t use some words as names because they are reserved for special use in JavaScript.

  • await
  • break
  • case
  • catch
  • class
  • const
  • continue
  • debugger
  • default
  • delete
  • do
  • else
  • enum
  • export
  • extends
  • false
  • finally
  • for
  • function
  • if
  • implements
  • import
  • interface
  • in
  • instanceof
  • let
  • new
  • null
  • package
  • private
  • protected
  • public
  • return
  • static
  • super
  • switch
  • this
  • throw
  • true
  • try
  • typeof
  • var
  • void
  • while
  • with
  • yield

You don’t have to memorise them; JavaScript will complain if you use any of them as a name:

let if = 5 // SyntaxError: Unexpected token 'if'

Now, let’s try something different


let x = 5

What does this do?


let x = 5
let x = 6

You can’t redeclare an existing variable in the same scope.


let x = 5
let x = 6 // SyntaxError

Scope


let x = 5
if (true) {
  let x = 6
}

This is allowed because the braces create a block and the block in turn creates a new scope for its variables.


let x = 5
if (true) {
  let x = 6
}

In that scope, the new x shadows the old one:


let x = 5
if (true) {
  let x = 6
  console.log(x) // 6
}

But only in that scope:


let x = 5
if (true) {
  let x = 6
  console.log(x) // 6
}
console.log(x) // 5

We say that variables declared in a block are local to the block:


let x = 5
if (true) {
  let x = 6 // x is local to the block
  console.log(x)
}

JavaScript also has a global scope containing several built-in bindings. Some global bindings we’ve already used are console, Number, String, and Boolean.

Variables are visible in their scope and in inner scopes:


let x = 5
if (true) {
  console.log(x) // 5
}

You can’t access a variable where it’s not visible:


if (true) {
  let x = 6
}
console.log(x) // ReferenceError

The same rules apply to deeper scopes:


let x = 5
let y = 7
if (true) {
  let x = 6
  if (true) {
    console.log(x)
    console.log(y)
    let z = 8
  }
  console.log(z)
}

The same rules apply to deeper scopes:


let x = 5
let y = 7
if (true) {
  let x = 6
  if (true) {
    console.log(x) // 6
    console.log(y)
    let z = 8
  }
  console.log(z)
}

The same rules apply to deeper scopes:


let x = 5
let y = 7
if (true) {
  let x = 6
  if (true) {
    console.log(x) // 6
    console.log(y) // 7
    let z = 8
  }
  console.log(z)
}

The same rules apply to deeper scopes:


let x = 5
let y = 7
if (true) {
  let x = 6
  if (true) {
    console.log(x) // 6
    console.log(y) // 7
    let z = 8
  }
  console.log(z) // ReferenceError
}

A final note is that you can’t use a variable before it is declared, even in the same scope:


console.log(x) // ReferenceError
let x = 5