Why doesn't strict mode limit identifiers to “eval” and “arguments” to label names?

So, as you know, strict JavaScript mode adds restrictions on the identifiers eval and arguments , effectively making them reserved words with two exceptions:

  • they can still be used as expressions, i.e. where expression is expected (with a few exceptions)
  • they can still be used as label names, and in the break / continue statements, label references.

Now I understand the first bullet. If, for example, the identifier eval not resolved as an expression (but the true reserved words were not), we would not be able to call the eval function at all (since eval(str) is an expression). The same goes for arguments — we need to be able to use it as an expression in order to have access to its elements (for example, arguments[0] ).

This rule has three exceptions. eval / arguments may not appear (1) as left expressions in assignments (e.g., eval = true; ), (2) as operands ++ / -- (e.g., eval++ ), (3) as delete operands (e.g., delete eval ). These are the only exceptions, although they are valid in all other context expressions.

What I do not understand is the second bullet. Why can they be used as shortcut names? For example, this code is valid even in strict mode:

 eval: for ( var i = 0; i < 10; i++ ) { arguments: for ( var j = 0; j < 10; j++ ) { if ( i < j ) continue eval; console.log( i - j ); } } 

Note that continue eval; refers to the eval label and has nothing to do with the actual eval function.

Also note how true reserved words cannot be used as label names. In my opinion, the intent of strict mode was to make the names eval and arguments as reserved words as possible. Then why store them as valid label names?

0
source share
1 answer

I don’t know why, but I can take a pretty good risk.

The reason eval and arguments limited to variable names (and, for that matter, why with forbidden) is that they affect the binding of variable names (i.e., to a local variable, a variable in the enclosing scope, or property on a global object if it exists). Without these restrictions, some names will be unconnected until run time, with all the dangers arising from this.

Label names occupy a different namespace from variable names, property names, etc. There has never been an ambiguity about the purpose of break / continue , since labels are statically assigned and links to labels are statically resolved. (Yes, eval code can include labels, but existing transitions cannot target these labels and cannot jump to eval code intended for existing labels, since label resolution occurs at compile time, and it is limited by the program to use the ECMAScript terminal name The script that contains the eval call is the Program, and the code executed by the eval call is the Program, but the two goals are completely separate for label targeting.)

The reason that eval and arguments forbidden for variable names just doesn't apply to labels. Thus, labels can still be called eval or arguments . It would be foolish to call this label like that, really. And if someone designs ECMAScript / JavaScript again, they will be keywords and will not be used as shortcut names. But there is no benefit in denying them label names and at least a little argument of compatibility for not prohibiting them, so they were not forbidden.

+1
source

All Articles