使用 JavaScript 的 with(){} 语句时,无效变量去了哪里?

Where do invalid variables go when using JavaScript's with(){} statement?

使用 JavaScript 的 with 语句时,名称无效的变量去哪里了?

var o = {"@#$%":1,"test":2}

with(o){
  console.log(test)
  // Can't do this:
  //console.log(@#$%)
  // Was it not imported, or is it just inaccessible?
}

您也可以在 JavaScript 引擎中引用代码吗?

如果 属性 不是有效的标识符,则不能像 with 中的标识符那样引用它。它并非不可访问,但您唯一的选择是手动查找原始对象上的 属性,就像正常情况一样:

var o = {"@#$%":1,"test":2}

with(o){
  console.log(o['@#$%']);
}

此类问题并非已弃用的 with 语句所独有。它也发生在全局对象中。就像with语句creates an object Environment Record一样,脚本中的所有代码在某种意义上都隐式地包装在全局对象(导致全局环境记录)的with中。

因此,出于完全相同的原因,当不能作为标识符的 属性 在 window 上时,例如:

window['###'] = 'foo';

如果不首先明确引用 window(或使用其他方法访问全局对象),则无法使用独立标识符访问 foo

(当然,就像 with 一样, 作为 window 上的标识符有效的属性可以单独引用 - 这就是为什么我们可以,例如,引用 undefinedArray 而不是 window.undefinedwindow.Array。这可以 )

Where do variables […] go?

我认为你搞反了。 with 语句不会创建任何变量(就像 var 声明那样),而是更改 scope 以便任何标识符都可以作为 属性 在对象上。每次访问 xyz 时,它看起来 if ('xyz' in o) return o.xyz else … - 这就是为什么 with 语句如此缓慢并且在严格模式下被弃用的原因。

所以根本没有 "variables that have invalid names"。如果您一开始就使用了无效的标识符,它会抛出语法错误,代码甚至不会 运行.