Brendan Eich (2013-12-20T03:05:13.000Z)
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.