Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No undeclared variable warning with function form of 'use strict' #3620

Open
elavy-harris opened this issue Jun 28, 2022 · 4 comments
Open

Comments

@elavy-harris
Copy link

elavy-harris commented Jun 28, 2022

I have the following JS file in Visual Studio Code with jshint v0.11.0:

"use strict";
function myfunction() {
    var a = b;
}

I get warnings to use the function form of 'use strict' (W097) and 'b' is not defined (W117). If I move "use strict" inside the function, I get no warnings at all. I believe that I should continue to get W117.

.jshintrc:

{
  "esversion": 6
}

jshint.config:

{
    "C_Cpp.errorSquiggles": "Enabled",
    "perl-toolbox.syntax.path": "D:\\Apps\\Perl64\\bin\\",
    "perl-toolbox.lint.brutal": "hint",
    "perl-toolbox.lint.cruel": "hint",
    "editor.suggestSelection": "first",
    "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
    "window.zoomLevel": 1,
    "jshint.config": ""
}

UPDATE
I've found that adding "undef": true, to .jshintrc causes the W117 warning to appear, but shouldn't the existence of "use strict" be enough?

@jugglinmike
Copy link
Member

Thanks for taking the time to write a report! This behavior surprised me, too. Here's what's going on:

One way to understand the net effect is that JSHint is simulating variable name resolution. JavaScript's global environment record is highly dynamic, so it's not possible to do this correctly just by looking at the source code. We're seeing an edge-case in a best-effort solution.

The inconsistency is jarring, though, and it's important to recognize that the behavior isn't directly tied to the interpretation of the language. The semantics of strict-mode code do not influence how bindings are resolved. As far as I can tell, automatically enabling undef like this was a creative attempt to help JSHint's users catch more mistakes. Although well-intentioned, it's also somewhat arbitrary (JSHint could enable any number of enforcing options when the code entered strict mode), so I'd be open to removing it.

Does that make sense, @elavy-harris? Do you have any opinion here?

@elavy-harris
Copy link
Author

Thank you @jugglinmike . I understand the idea of turning on undef for strict mode. What I don't understand is why global strict mode behaves differently than function strict mode. Is the distinction that in the latter case, the top-level scope evaluation is performed without strict mode and therefore undef is false? That would seem to be the case, as turning on undef inside the function seems to have no effect.

I'm pretty new to this environment, so that limits the value of my opinion. I would guess, though, that there are a lot of people using global strict mode and that they would be very unhappy if you remove "auto-undef". If you can't turn on undef inside the function, I'd just be resigned to the "jarring inconsistency" and let it go.

@jugglinmike
Copy link
Member

In regard to the undef option, JSHint interprets global strict mode in the same way as function strict mode: it enables the option for the current scope.

Another way to understand this is that undef only makes sense if it's enabled at the top-level because that's where it is ultimately enforced. No matter where an undefined variable is referenced, it is ultimately recognized as undefined at the top-level (since JavaScript's resolution algorithm starts at the local scope and travels to each containing scope until it finds a definition).

Does that clear things up at all?

The takeaway here is in order to enforce this behavior consistently, don't rely on the presence of the "use strict" directive. Instead, explicitly enable the undef option at the top-level of the code or in a JSHint configuration file.

@elavy-harris
Copy link
Author

I think it does. Thanks.

nhanb added a commit to nhanb/neodots that referenced this issue Oct 29, 2023
... in function-based "use strict":
<jshint/jshint#3620>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants