【问题标题】:Where do invalid variables go when using JavaScript's with(){} statement?使用 JavaScript 的 with(){} 语句时,无效变量会去哪里?
【发布时间】:2020-02-10 02:18:59
【问题描述】:

在使用 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 引擎中引用代码吗?

【问题讨论】:

标签: javascript scope internals scope-chain


【解决方案1】:

如果属性不是有效标识符,则不能像 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 上的标识符有效的属性可以单独引用 - 这就是为什么我们可以引用 undefined 和 @ 987654335@而不是window.undefinedwindow.Array。这个可以cause bugs...)

【讨论】:

  • 谢谢,在提供与窗口对象的类比并参考在 ECMA 规范中找到更多详细信息的位置方面做得很好。
【解决方案2】:

变量 […] 去哪里了?

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

因此根本不存在“具有无效名称的变量”。如果您一开始就使用了无效的标识符,则会引发语法错误,并且代码甚至无法运行。

【讨论】:

    猜你喜欢
    • 2014-06-27
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2014-05-14
    • 2013-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多