Why doesn't strict mode restrict the identifiers “eval”, and “arguments” from appearing as label names?

走远了吗. 提交于 2019-12-12 03:46:01

问题


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

  • they can still be uses as expressions, i.e. in places where an expression is expected (with a couple of exceptions, though),
  • they can still be used as label names, and in break/continue statements to reference labels.

Now, I understand the first bullet. If, for instance, the identifier eval wasn't allowed as an expression (and true reserved words aren't), we wouldn't be able to invoke the eval function at all (since eval(str) is an expression). Same goes for arguments - we need to be able to use it as an expression in order to be able to access its elements (e.g. arguments[0]).

This rule has a three exceptions, though. eval/arguments may not appear (1) as left-hand side expressions in assignments (e.g. eval = true;), (2) as operands of ++/-- (e.g. eval++), (3) as operands of delete (e.g. delete eval). Those are the only exceptions though, and in all other expression-contexts, they are valid.

What I don't understand is the second bullet. Why can they be still used as label names? For instance, 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 );    
    }        
}

Notice how continue eval; references the eval label, and has nothing to do with the actual eval function.

Also, notice how true reserved words cannot be used as label names. From my understanding, the intend of strict mode was to make the names eval, and arguments as reserved-word-like as possible. Then why keep them as valid label names?


回答1:


I don't know why, but I can hazard a pretty good guess.

The reason eval and arguments are restricted for variable names (and, for that matter, why with is forbidden) is that they affect where variable names bind (i.e. to a local variable, a variable in an enclosing scope, or to a property on the global object if one exists). Without those restrictions, some names are unbound until runtime, with all the hazards that implies.

Label names occupy a different naming space from variable names, property names, and so on. There's never ambiguity about the target of a break/continue, because labels are statically assigned and label references are statically resolved. (Yes, eval code can include labels. But existing jumps can't target those labels, nor can jumps in eval code target pre-existing labels, because label resolution occurs at compile time, and it is scoped to a Program, to use the ECMAScript terminal's name. A script that contains an eval call is a Program, and the code executed by the eval call is a Program, but the two are entirely separate for label-targeting purposes.)

The reason to forbid eval and arguments for variable names simply doesn't apply to labels. Therefore, labels can still be named eval or arguments. It would be stupid to name a label that way, true. And if someone were designing ECMAScript/JavaScript again, they'd be keywords, and not usable as label names. But there's no gain to be had from forbidding them as label names, and at least a small compatibility argument for not forbidding them, so they were not forbidden.



来源:https://stackoverflow.com/questions/12557574/why-doesnt-strict-mode-restrict-the-identifiers-eval-and-arguments-from-ap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!