Brendan Eich (2013-12-20T03:05:13.000Z)
Andrea Giammarchi wrote:
> why is this not possible, giving the ability to understand through 
> typeof if there is a value or not?
>
> ```javascript
> // defined as const
> // reserved in this scope
> // but not assigned yet
> const WHATEVER;
> if (condition) {
>   // first come, first serves
>   WHATEVER = 123;
>   // that's it! const defined for the whole scope
>   // immutable from now on
> } else {
>   WHATEVER = 456;
> }

Past JS2/ES4 designs have allowed this, but it requires definite 
assignment analysis and use-before-defining-assignment error checking.

In general, such checks can't be static in JS, so the language and VM 
complexity blow up a bit with runtime checking for an "uninitialized" 
(not same as undefined) sentinel value that must be guarded against by a 
read barrier where it can't be proven unnecessary.

This is pretty obnoxious for implementors, not great for users either 
(did I declare const IMPORTANT; and forget to assign IMPORTANT= in some 
branch of control flow that my tests miss?).

It's not in Harmony. We require an initialiser as part of the const 
declaration syntax. What you are doing here, by many measures, is 
varying a variable from its default (undefined) value to a new value.

If you want that variable to stop varying after, and you need it as a 
global (window) object property anyway, use Object.defineProperty to 
make it non-writable.

BTW, the last version your head post gave,

const ES6_PROXY = function(){
   try {
     new Proxy({},{});
     return true;
   } catch(o_O) {
     return false;
   }
}();

isn't bad at all, but are you really concerned about false-positive 
(typeof Proxy != "undefined") test results? Some other Proxy could 
easily be a function that does not throw when called with two objects as 
arguments. The standard object detection pattern:

if (typeof Proxy == "undefined")
   this.Proxy = (/* polyfill Proxy here somehow... */);

often has a leading

var Proxy;
if (typeof Proxy == "undefined")
   this.Proxy = (/* polyfill Proxy here somehow... */);

precisely to avoid errors from static analyzers looking for bare Proxy 
uses without a declared var in scope.

In any event, these patterns want *variables*, not constants, because 
they must work when there's already a binding. And you cannot redeclare 
with const (or let or class), as Rick points out.

/be
domenic at domenicdenicola.com (2014-01-06T13:48:24.151Z)
Andrea Giammarchi wrote:
> why is this not possible, giving the ability to understand through 
> typeof if there is a value or not?
>
> ```javascript
> // defined as const
> // reserved in this scope
> // but not assigned yet
> const WHATEVER;
> if (condition) {
>   // first come, first serves
>   WHATEVER = 123;
>   // that's it! const defined for the whole scope
>   // immutable from now on
> } else {
>   WHATEVER = 456;
> }
> ```

Past JS2/ES4 designs have allowed this, but it requires definite 
assignment analysis and use-before-defining-assignment error checking.

In general, such checks can't be static in JS, so the language and VM 
complexity blow up a bit with runtime checking for an "uninitialized" 
(not same as undefined) sentinel value that must be guarded against by a 
read barrier where it can't be proven unnecessary.

This is pretty obnoxious for implementors, not great for users either 
(did I declare const IMPORTANT; and forget to assign IMPORTANT= in some 
branch of control flow that my tests miss?).

It's not in Harmony. We require an initialiser as part of the const 
declaration syntax. What you are doing here, by many measures, is 
varying a variable from its default (undefined) value to a new value.

If you want that variable to stop varying after, and you need it as a 
global (window) object property anyway, use Object.defineProperty to 
make it non-writable.

BTW, the last version your head post gave,

```js
const ES6_PROXY = function(){
   try {
     new Proxy({},{});
     return true;
   } catch(o_O) {
     return false;
   }
}();
```

isn't bad at all, but are you really concerned about false-positive 
(typeof Proxy != "undefined") test results? Some other Proxy could 
easily be a function that does not throw when called with two objects as 
arguments. The standard object detection pattern:

```js
if (typeof Proxy == "undefined")
   this.Proxy = (/* polyfill Proxy here somehow... */);
```

often has a leading

```js
var Proxy;
if (typeof Proxy == "undefined")
   this.Proxy = (/* polyfill Proxy here somehow... */);
```

precisely to avoid errors from static analyzers looking for bare Proxy 
uses without a declared var in scope.

In any event, these patterns want *variables*, not constants, because 
they must work when there's already a binding. And you cannot redeclare 
with const (or let or class), as Rick points out.