简体   繁体   中英

Why are implicit variables configurable, while explicit variables and function declarations are not?

Why are implicit variables configurable, while explicit variables and function declarations are not?

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

Related .

Variables get put into the current scope, or Lexical Environment (an internal map of variable names to the values they contain) only when the variables are declared - that is, with const , let , or var .

If this happens, those variables are not deletable; they can't be removed from a scope once declared. On the top level, global variables with var are assigned to the global object. The property is not removeable from the global object because the identifier is not deletable from the global scope - so, it's not configurable.

When you don't declare a variable, you assign to a property of the global object in sloppy mode, but you don't create an identifier for the global lexical environment. It's just a property of the global object, not a standalone variable name, so it's deletable (and thus configurable).

There is no such thing as an implicit variable declaration in JavaScript.

In non-strict mode, if foo has not been declared, and regardless of whether we are in the global context, then:

foo = 'bar'

is equivalent to:

globalThis.foo = bar

This follows the normal JavaScript behavior of adding a new property to an object. The resulting property is configurable by default.

Whereas a variable declaration in the global context, like so:

var foo = 'bar'

...follows a different logical process ( GlobalDeclarationInstantiation ), part of which involves the addition of the identifier to a [[VarNames]] internal slot (in CreateGlobalVarBinding ), which is peculiar to the the global environment record . Its specific purpose appears to be to permit the distinguishing between properties on the global object intended to be properties, and properties on the global object intended to be variables. As part of this process CreateGlobalVarBinding is invoked with false as the second argument, meaning the resulting property on the global object is non-configurable.

So although, in the global context, both foo = 'bar' and var foo = 'bar' result in a property on the global object, one is an ordinary property and the other is an ordinary-property-with-special-metadata-and-handling-logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM