2

From MDN article about strict mode:

First, strict mode makes it impossible to accidentally create global variables. In normal JavaScript mistyping a variable in an assignment creates a new property on the global object and continues to "work" (although future failure is possible: likely, in modern JavaScript). Assignments, which would accidentally create global variables, instead throw an error in strict mode:

'use strict';
                       // Assuming a global variable mistypedVariable exists
mistypeVariable = 17;  // this line throws a ReferenceError due to the 
                       // misspelling of variable

What does this mean? Does the engine detect if a variable with a similar name already exists(?!) or does strict mode merely prohibit declaring global variables outside of global scope?

The above quotation seems to hint the first possibility but this seems... weird?

  • 2
    I think your confusion comes from the idea that `mistypeVariable = 17;` is a proper declaration. It would be in sloppy mode, but in strict mode this is *not* a variable creation, so unless you already had a `let` or `var` for it, it is an error. – trincot Dec 20 '18 at 20:35
  • I'm not sure I understand the question. In strict mode, this will throw an error. In "sloppy mode", it will implicitly create a global called `mistypeVariable`, with value 17 - which is almost always much less helpful behaviour. (Even if that global never gets in your way, which it probably won't, you won't be aware of the mistake until later when you're trying to figure out some strange bug.) – Robin Zigmond Dec 20 '18 at 20:36
  • @trincot (1) so how to declare globals in strict? or does strict prohibit globals at all? (2) As per my quotation: "***Assuming a global variable mistypedVariable exists** this line throws a ReferenceError*" - emphasis mine. My understanding is that JS engine must therefore check for similar names?? –  Dec 20 '18 at 20:37
  • @RobinZigmond Yes but does strict mode prevent implicit declarations *only if similarily named variables already exist*? This part I marked in italics confuses me –  Dec 20 '18 at 20:39
  • @gazkam of course you can create globals in strict mode - but only by declaring them (with `var`, `let` or `const`) in the global scope. Which is how you should be doing them anyway (if you must use globals at all). What strict mode prevents is the *accidental* creation of globals through using undeclared variables (eg. from a typo) – Robin Zigmond Dec 20 '18 at 20:39
  • No JS engine has any conception of "similarly named". Variable names are either the same, or different. – Robin Zigmond Dec 20 '18 at 20:40
  • 1
    I think your confusion stems from interpreting that comment in your quoted snippet too literally. The error is not thrown because of any perceived "similarity of name" to another variable, it's thrown pure and simply because you're using an undeclared variable. It doesn't matter what other variable names you're using. – Robin Zigmond Dec 20 '18 at 20:41
  • @RobinZigmond That makes sense to me! But again - from my quotation: "*Assuming a global variable mistypedVariable exists(!!)*" the assignment "mistypeVariable=17" fails. Only assuming that mistype**d**Variabled exists?!?! –  Dec 20 '18 at 20:41
  • 2
    The comment in the quoted code is misleading: The "Assuming" part is irrelevant. It should really read: *"Assuming that **no** variable with **exactly** this name was defined with `let` or `var`,..."* But note what the purpose was of the code snippet and the comment: to show that in strict mode it is much easier to spot spelling mistakes. – trincot Dec 20 '18 at 20:42
  • @AndrewL sorry for rollback but the code **is** part of the quotation so I believe it should be marked as such? –  Dec 20 '18 at 20:43
  • Possible duplicate of [What does "use strict" do in JavaScript, and what is the reasoning behind it?](https://stackoverflow.com/questions/1335851/what-does-use-strict-do-in-javascript-and-what-is-the-reasoning-behind-it) – Patrick Roberts Dec 20 '18 at 20:46
  • @trincot @ RobinZigmond Thank you for your latest comments! Make it an answer and I'll accept it :) –  Dec 20 '18 at 20:46
  • @RobinZigmond See above. –  Dec 20 '18 at 20:46
  • @gazkam done :) (Although I see trincot got in there first :) ) – Robin Zigmond Dec 20 '18 at 20:51

3 Answers3

2

The comment in the quoted code is misleading: The "Assuming" part is irrelevant. It should really read: "Assuming that no global variable with exactly this name was defined with let or var,..."

But do note what the purpose was of the code snippet and the comment: to show that in strict mode it is much easier to spot spelling mistakes. In sloppy mode the spelling mistake would go unnoticed (no errors) and you would be working with two variables without knowing it (at least for a while)

trincot
  • 317,000
  • 35
  • 244
  • 286
2

As requested, I'll make this into an answer :)

I think you understand what happens here already, and are just getting confused through reading that quote about "assuming a global variable..." too literally. (I will admit it is phrased in such a way as to possibly lead to this confusion though.) The real situation is very simple, and has nothing to do with variables having "similar names" (which JS has no concept of):

What is being talked about is what happens if you assign a value to a variable which has not been formally declared (variables are declared with one of the keywords var, let or const). Not declaring your variables is bad practice, and in strict mode will throw an error - this is a good thing and warns you of your mistake. But in non-strict mode, JS will happily accept this and think you wanted to declare a global variable of that name. This is almost never what you actually want, as it pollutes the global namespace, doesn't inform you of your error, and may lead to all sorts of tricky bugs later.

Robin Zigmond
  • 17,805
  • 2
  • 23
  • 34
0

does strict mode merely prohibit declaring global variables outside of global scope?

strict mode definitely doesn't prohibit declaring global variables from anywhere. In non-strict mode, if you write:

someVar = 't';

it will evaluate to:

window.someVar = 't';

( why is this happening? ) despite of writing inside or outside of a function scope. actually, the line was both declaring and evaluation of variable ( look again, it doesn't have var so it shouldn't declare anything! ).

But it would cause such a side-effect that wasn't totally fine and they've introduced strict-mode which when is active, our first line will throw an error. because it's just evaluation without declaring it first.

now if you need to manipulate global scope inside of a function scope, you only should global object as reference:

var someGlobalVar;
var someOtherGlobalVar;

function hello() {

    // this will make *someGlobalVar* to be redefined in the inner scope
    // someGlobalVar != window.someGlobalVar
    var someGlobalVar;

    // manipulating inner variable, not global one
    someGlobalVar = 's';


    // it's fine, you've accessed global object correctly
    window.someGlobalVar = 's';


    // you're still editing global object, because
    // there's no other variable inside of this scope having the same name
    someOtherGlobalVar = 's';

}
mrReiha
  • 908
  • 6
  • 24