2

I'm learning JS by reading a book (Learning JavaScript by Ethan Brown) where author writes:

Lexical scoping means whatever variables are in scope where you define a function from (as opposed to when you call it) are in scope in the function. Consider this example:

const x = 3;

function f() {
  console.log(x); // this will work
  console.log(y); // this will cause a crash
}
const y = 3;
f();

The variable x exists when we define the function f , but y doesn’t. Then we declare y and call f , and see that x is in scope inside the body of f when it’s called, but y isn’t. This is an example of lexical scoping: the function f has access to the identifiers that were available when it was defined, not when it was called

When I run it in VS Code debugger, there doesn't seem to be any errors.

I see

3

3

without any exceptions. Can this depend on ES version that I'm using or something else?

Community
  • 1
  • 1
Liam Kernighan
  • 2,335
  • 1
  • 21
  • 24
  • 4
    That is a bad bit of sample code. The author is simply wrong. – Pointy Nov 05 '18 at 23:10
  • 1
    To add to what @Pointy is saying, the scope isn't assigned when the function is defined and compiled rather it's assigned at runtime i.e. when the function is called. – Adam H Nov 05 '18 at 23:11
  • 1
    `y` isn't in the scope of `f`, but it's defined in an enclosing scope (in this case the global scope) so it can be accessed with no problems. Sounds like this book doesn't explain scope very well. (The best discussion of JS scope I know of is in this book: https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/README.md#you-dont-know-js-scope--closures) – Robin Zigmond Nov 05 '18 at 23:11
  • 1
    Here is a good write up with examples to help you understand Lexical scope. https://stackoverflow.com/a/1047491/9898651 – Adam H Nov 05 '18 at 23:13
  • @RobinZigmond very nice article. Thanks a lot) – Liam Kernighan Nov 05 '18 at 23:16
  • 1
    @Pointy's comment should be the answer. The author of the book has made a mistake, there's no two ways about it. – noppa Nov 05 '18 at 23:19
  • Everything is declared so yes it works. Burn the book and start writing code, that is the way to learn. Oh, and this forum is helpful too :) – Michelangelo Nov 05 '18 at 23:33
  • The author explained lexical scoping and closures correctly, but JS is a bit special: it hoists variable declarations to the beginning of the enclosing scope, i.e. a variable's scope may start before its declaration. (Does this also hold for let-variables?) – amon Nov 05 '18 at 23:39

3 Answers3

4

Though I think the author simply chose a poor (well, incorrect) piece of code to illustrate the point, the code is interesting as a way to illustrate something related but different. Because y is declared with const, it is visible inside the function because its declaration is hoisted to the nearest enclosing block (which is not explicitly visible in the posted code, but it must be there somewhere). However, if the function call is moved to before that declaration, you will see an error because the reference to y will happen in the somewhat weirdly-named "temporal dead zone". References to declared but uninitialized variables created with let or const are runtime errors.

If the declaration of y is changed to a var declaration, then moving the function call to before variable declaration does not cause an error because the variable is defined and in scope but is simply (old-school) uninitialized, and therefore simply undefined.

Pointy
  • 405,095
  • 59
  • 585
  • 614
3

This works because const y=3 is declared before f() is called. If you move the declaration of y after f() then it will work as "expected"

0

In simple words, lexical scoping allows you to access the variables, properties and functions of the outer function in the inner function.

For example:

function outer(){
   let username="Pratham";
   function inner(){
    console.log(username);
   }
inner();
}
outer();

In this code, the username variable belongs to the outer function but we can use it in the inner function with the help of lexical scoping.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83