【问题标题】:Why are implicit variables configurable, while explicit variables and function declarations are not?为什么隐式变量是可配置的,而显式变量和函数声明却不是?
【发布时间】:2020-04-09 11:32:04
【问题描述】:

为什么隐式变量是可配置的,而显式变量和函数声明却不是?

foo = ''
console.log(Object.getOwnPropertyDescriptor(window, 'foo')) // configurable: true

var bar = ''
console.log(Object.getOwnPropertyDescriptor(window, 'bar')) // configurable: false

Related.

【问题讨论】:

  • 隐式创建的变量没有被声明。
  • 这听起来像是对问题的重述?
  • 解释MDN ref
  • 事实上,这是一个很好的解释。 foowindow 的属性,因此您可以像操作它一样操作它……嗯,一个普通属性。然而bar 是一个声明的变量,它也恰好是window 的一个属性。所以,配置它会导致奇怪的行为——使var不可写是什么意思,现在它是一个常量吗?但是等等,它不能,因为它是一个var 变量,所以如果你不能写入它就会不一致。
  • 好吧,我删除了“因为”,在您询问不存在的“声明的隐式变量”的编辑之前。不过,这也是一种解释。

标签: javascript


【解决方案1】:

仅当变量被声明时,变量才会被放入当前作用域或词法环境(变量名称到它们所包含的值的内部映射)——也就是说,使用const,@ 987654325@,或var

如果发生这种情况,这些变量是不可删除的;一旦声明,它们就不能从范围中删除。在顶层,带有var 的全局变量被分配给全局对象。该属性不可从全局对象中删除,因为标识符不可从全局范围中删除 - 因此,它不可配置。

当您不声明变量时,您会在草率模式下分配给全局对象的属性,但您为全局词法环境创建标识符。它只是全局对象的一个​​属性,而不是一个独立的变量名,所以它是可删除的(因此是可配置的)。

【讨论】:

  • var 声明似乎放在VariableEnvironment 中,我认为这与LexicalEnvironment 略有不同。是在 ECMAScript 规范的 globalThis 部分创建属性,还是 W3C 标准行为 - 我正在规范中寻找它。
  • @52d6c6af 它是 ES 的一部分。如果我没记错的话,从版本 1 开始。
  • @52d6c6af 见here: For each String vn in declaredVarNames, in list order, do: Perform ? envRec.CreateGlobalVarBinding(vn, false)` 其中第二个参数确定属性是否可配置。
  • 全局绑定似乎直接定位在全局对象上,该对象本身被定位为全局环境的“基础”(可能与继承一样)。所以全局对象本身就是全局词法环境的一部分。这向我表明隐式和显式变量声明最终都在同一个地方,但我还没有找到关于隐式变量的信息。第2段here.
  • 我能找到的CreateGlobalVarBinding(F, true)的唯一实例是7.a.i.i here
【解决方案2】:

在 JavaScript 中没有隐式变量声明。

在非严格模式下,如果foo没有被声明,并且不管我们是否在全局上下文中,那么:

foo = 'bar'

相当于:

globalThis.foo = bar

这遵循向对象添加新属性的正常 JavaScript 行为。结果属性默认是可配置的。

而全局上下文中的变量声明,如下所示:

var foo = 'bar'

...遵循不同的logical processGlobalDeclarationInstantiation),其中一部分涉及将标识符添加到[[VarNames]]内部插槽(在CreateGlobalVarBinding中),这是特有的全球环境记录。它的特定目的似乎是允许区分打算作为属性的全局对象上的属性和打算作为变量的全局对象上的属性。作为此过程的一部分,CreateGlobalVarBinding 被调用,false 作为第二个参数,这意味着全局对象上的结果属性是不可配置的。

因此,尽管在全局上下文中,foo = 'bar'var foo = 'bar' 都导致全局对象上的属性,一个是普通属性,另一个是普通属性和特殊元数据和-处理逻辑。

【讨论】:

    猜你喜欢
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 2012-10-22
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多