Skip to content

let assigment breaks typeof #33462

Description

@mariorodriguespt

What steps will reproduce the bug?

> let a = a || 2;
Uncaught ReferenceError: Cannot access 'a' before initialization
> typeof a !== 'undefined'
Uncaught ReferenceError: a is not defined
> typeof b !== 'undefined'
false

How often does it reproduce? Is there a required condition?

Every single time. If you use let to define a variable and in the assignment part you check if the same variable exists, you won't be able to use typeof after.

What is the expected behavior?

I would expect typeof should always work regardless of the variable a existing or not.

What do you see instead?

Uncaught ReferenceError: a is not defined

Additional information

This appear to be an issue in Chromium since it works as expected in Firefox.

Activity

  1. added
    v8 engineIssues and PRs related to the V8 dependency.
    and removed
    v8 engineIssues and PRs related to the V8 dependency.
    on May 19, 2020
  2. devsnek commented on May 19, 2020

    @devsnek
    Member

    Duplicate of #8309, albeit a much more confusing one.

  3. added
    duplicateIssues and PRs that are duplicates of other issues or PRs.
    replIssues and PRs related to the REPL subsystem.
    on May 19, 2020
  4. devsnek commented on May 19, 2020

    @devsnek
    Member

    Also, you've technically found a bug in firefox. If you feel like it you can report it here: https://bugzilla.mozilla.org/

  5. mariorodriguespt commented on May 19, 2020

    @mariorodriguespt
    Author

    This is working well for me on Firefox 76.0.1 (64-bit)
    Screenshot from 2020-05-19 03-49-58

    Could you share your reproduction steps?

  6. devsnek commented on May 19, 2020

    @devsnek
    Member

    @mariorodriguespt it should be throwing in firefox. This is the same case as { typeof x; let x; }

  7. mariorodriguespt commented on May 19, 2020

    @mariorodriguespt
    Author

    It is not throwing on Firefox and it is correct.
    It throws an error when you try let a = a || 2 but the typeof works as expected.

    On your example, Firefox does throw an error: ReferenceError: "can't access lexical declaration x' before initialization"` which is correct due to the order.

    As far as I can tell, V8 is not handling this correctly: The assignment failed but the typeof got broken, this issue is more relevant on a browser environment where you have a second script checking a var using typeof.

  8. devsnek commented on May 19, 2020

    @devsnek
    Member

    When you do let x = /* something that throws an error */, the variable is created, but is never initialized. This state is called the "temporal dead zone" (https://snek.dev/blag/2019-07_js_hoisting might help). While a variable is in the temporal dead zone, typeof x will throw, because the variable exists and is resolvable, but getting its value to try to get the type of it throws a reference error. V8 is behaving correctly here, and firefox has a bug.

  9. mariorodriguespt commented on May 19, 2020

    @mariorodriguespt
    Author

    Just opened a bug on Firefox, I'll leave the link for those interested in the follow up: https://bugzilla.mozilla.org/show_bug.cgi?id=1639078

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateIssues and PRs that are duplicates of other issues or PRs.replIssues and PRs related to the REPL subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions