2

I've been playing around with JavaScript to learn some concepts, and stumbled across this small example.

Consider the function:

function foo() {
  console.log(x);
}

and then, run:

> foo(); let x = 10;

I get the expected:

ReferenceError: x is not defined
    at foo (repl:2:13)

But, surprisingly, I neither cannot define x

> let x = 10;
SyntaxError: Identifier 'x' has already been declared

nor reassign it

> x = 10;
ReferenceError: x is not defined

Is this behavior expected? What's the state of x?

Edit:

Example on Google Chrome:

Example on Google Chrome

nicodp
  • 2,362
  • 1
  • 11
  • 20
  • Are you trying this out inside the browser? Because this does not make sense when you try this out on an actual editor apart from re-declaring it. – Rohit Kashyap Sep 22 '19 at 20:22
  • @RohitKashyap Tried it inside of Chrome and in Node, same behavior – nicodp Sep 22 '19 at 20:23
  • 1
    @charlietfl the issue is that the state of the scope of Chrome's console and Node is (or looks like) broken: it doesn't let me declare `x` or use it again. – nicodp Sep 22 '19 at 20:24
  • It's true that you cannot declare it again, but the reassigning works fine on my machine. – Rohit Kashyap Sep 22 '19 at 20:25
  • 1
    @RohitKashyap did you run this as a one-liner? `foo(); let x = 10;` – nicodp Sep 22 '19 at 20:26
  • Yes I did and it works fine. – Rohit Kashyap Sep 22 '19 at 20:28
  • @RohitKashyap Tried on Safari, same behavior. Did you run it on Firefox? – nicodp Sep 22 '19 at 20:29
  • Ran it on chrome. – Rohit Kashyap Sep 22 '19 at 20:30
  • @RohitKashyap can you take a look at this, to see if it's the same? https://i.imgur.com/5c3106O.png – nicodp Sep 22 '19 at 20:32
  • @nicodp I see this same behaviour on chrome. – kvsm Sep 22 '19 at 20:36
  • 1
    "*Is this behavior expected?*" - Yes. "*What's the state of x?*" `x is not defined` is not a good error message. It should be `x was not initialised` or `x is uninitialised`. – Bergi Sep 22 '19 at 20:40
  • @Bergi: yes, but why does `x = 10` throw? Can an assignment ever throw? – georg Sep 22 '19 at 20:45
  • @georg Yes, any usage of an uninitialised variable does throw. Just like it does in `{ x = 10; let x; }`. (Although the error message for that is much better: `Cannot access 'x' before initialization`). – Bergi Sep 22 '19 at 20:47
  • @Bergi so if I understand correctly, the `let x` gets hoisted, the call to `foo` throws the error so `x` never gets initialized. But why you can't reassign it thereafter? – nicodp Sep 22 '19 at 20:53
  • @Bergi: so Firefox is wrong? https://i.stack.imgur.com/NpqeH.png – georg Sep 22 '19 at 20:55
  • @georg Looks like it, yes. Or put in other words: it might have a more user-friendly debugger console, which is able to clean up redeclaration mistakes. Or maybe it runs the latter lines in different scopes. Who knows. – Bergi Sep 22 '19 at 21:00
  • @nicodp "*But why you can't reassign it thereafter?*" - because it's still declared and uninitialised. See the duplicate for more explanation of this behaviour. – Bergi Sep 22 '19 at 21:00
  • @Bergi the answer made things clear, thanks! – nicodp Sep 22 '19 at 21:05

0 Answers0