Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript const scope and curly braces

As I understand the scope of const is curly braces (block). However, when I run the following code in browser (FF) it doesn't give any error. Is the following JS code right? Please, explain.

 <script type="text/javascript">
 {
     const Foo = "foo";        
 }
 </script>
 <div></div>
 <script type="text/javascript">
 {
     Foo = null;
 }
 </script>
like image 496
Pavel_K Avatar asked Jan 29 '23 12:01

Pavel_K


2 Answers

You will not get error because,

Below code says you are using const variable of Foo inside this code block, the const Foo will bot be accessible out side of the block

 {
     const Foo = "foo";        
 }

Below code says you are assigning the variable Foo with value of null, which will bind to window object,

 {
    Foo = null;
 }

so Foo = null; which binds to window object and const Foo='foo' is a constant variable for the particular code block

So when you are assign Foo=null it assigns the variable to window object and you can access it like ,

  window.Foo

i.e. any variable which declare without var it will bind to window object,

like image 148
programtreasures Avatar answered Jan 31 '23 08:01

programtreasures


You are aware that using const will create a constant in a given scope. Look at your example:

<script type="text/javascript">
{
   const Foo = "foo";        
}
</script>
<div></div>
<script type="text/javascript">
{
   Foo = null;
}
</script>

You can reduce the above to the following code:

{
   const Foo = "foo";        
}
{
   Foo = null;
}

Since you have declared and initialized Foo in a scope (denoted by using { and }), then Foo is only known to that scope. Let's call that scope A. When issuing Foo = null;, you are in a different scope: B. When assigning a value to a variable, the engine always checks if the variable name is not bound in the current execution context. In short, it checks

  1. if Foo exists in the local scope: the answer is no. Your Foo = "foo" is only known to the scope A. Not in the current scope.
  2. if Foo exists in the scope chain: the answer is no. There is no declarations made in the parent scope.
  3. if Foo is known to the global execution context (aka window scope): the answer is no.

End result: the assignment will occur. But since you did not have provided any assignment statements: const, let or var. Therefore, Foo=null will be added to the window scope. If you do window.Foo, you will get a response with null.

However, it has to be noted that there should be an error. But Javascript is a language that "serves" the developer. Instead of spitting you with an error, it will silent that error and hook Foo to the window object. If you use strict mode, then it will throw an error. (please consult the MDN page for further information)

To comprehend it a better, look to the following examples that is executed in a non-strict environment and think first if there would be an error or not.

<script type="text/javascript">
{
     const Foo = 'hello';
     Foo = 555; // success or fail ?
}
</script>

The answer is no. You are aware of that. It fails the first check: Foo is already bound in the same scope.

<script type="text/javascript">
{
     const Foo = 'hello';
     {
        Foo = 555; // success or fail ?
     }
}
</script>

The answer is yes. It will fail because it fails the second check (see the list above). Foo = 555; is called in a scope: B. Scope B has a parent scope: A where Foo is known.

Now, something tricky:

<script type="text/javascript">
    {
        window.Foo = 'hello';
        {
            Foo = 555; // success or fail ?
        }
    }
</script>

What do you think? 🙂

...

it works. Do you not believe me: check it here below:

{
  window.Foo = 'hello world';
  console.log('window.Foo?', window.Foo); // shows hello world
  {
    Foo = 555;
    console.log('window.Foo?', window.Foo); // shows 555
  }
}

that is because adding variables to the window scope (although it is not recommendable to do so) does not make it read-only. You can change it afterwards as desired.

like image 28
KarelG Avatar answered Jan 31 '23 09:01

KarelG