Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson
1×
Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.

Autoplay

    Working with var, let, const, and block scopes

    Tyler ClarkTyler Clark
    javascriptJavaScript

    {} is overloaded to be either an object literal or a block scope. When an assignment is made to a variable inside of the {}, it then becomes a block scope. Otherwise it is treated as an object literal.

    var, let, and const respect block and function scopes differently. var is also hoisted and can be redeclare while that is not true for let and const. This lesson goes more in depth on scope and how each variable declaration treats it differently.

    Code

    Code

    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson
    Discuss

    Discuss

    Transcript

    Transcript

    Instructor: Block scoping in JavaScript is defined with the overloaded opening and closing curly braces. It does not become a scope until there is an assignment made inside of it. If no assignment is made, JavaScript will treat it as an object literal, and create a new object.

    When trying to determine block scopes in your code, you cannot simply look for just curlies, because objects are not scoped, and they do have curlies. Here we see an open and close curly braces, and we also see an assignment made on line four, thus making it a block scope.

    Now that we've established we have a block scope created, we next need to understand what variable types we're working with. Here we see that we're using two vars. Vars, however, do not respect block scopes, only function execution scopes.

    You might expect the console log here to print Clark and the last one to print Tyler because the vars are used in two different block scopes. However, like I said, vars only reference function execution context scopes.

    What is our execution of our context here? It's the global namespace or window object. When we re-declare on line four, we're leaving the block scope and redefining the value on line one. In order to scope the var correctly, we need to change our block scope to a function scope. Now, when we invoke our function and look at the two console logs, we see that it is Clark and Tyler.

    Some other notes on vars is that before our JavaScript is processed, all var declarations are hoisted only to the top of their execution context with an initial value of undefined. Our code actually looks like this behind the scenes, with an initial value of undefined.

    Also, any vars declared in a global function context are placed on the window object. If we did window.firstName, we would get Tyler, not Clark again because it is scoped to this function context.

    Let's go back to our original block scope code and instead of vars, let's use the let variable declaration and see how it responds. We see that unlike our var example, let does scope to block scopes, as well as function execution scopes.

    We have two different console at log values because these are actually two different variables. Also, unlike var, let is only initialized to a value when the parser evaluates it. In other words, it's not hoisted to this top of the scope with an initial value of undefine like var is.

    Finally, if we tried to re-declare let within the same scope, it would throw an error while using a var would not. Const has the same rules as let does. Even if we changed our two variables to const, we still get two different console log values because we're creating two different variables within a block scope which it respects.

    It does not hoist. It cannot be re-declared. However, it has a special rule that states that it can also not be redefined with a different value. We cannot later on change the value to something else because it will throw an error.

    The caveat on this is that it does not do a deep equal. You can mutate properties within an object and an array, for example, and no error will be thrown.