Just check if your reassignment is valid:
var isConst = function(name, context) { // does this thing even exist in context? context = context || this; if(typeof context[name] === "undefined") return false; // if it does exist, a reassignment should fail, either // because of a throw, or because reassignment does nothing. try { var _a = context[name]; context[name] = !context[name]; if (context[name] === _a) return true; // make sure to restore after testing! context[name] = _a; } catch(e) { return true; } return false; }.bind(this);
You need to try / catch, because override Can throws an exception (for example, in Firefox), but when it is not (for example, in Chrome), you just check if something really changed the value of "this always changes the value" .
A simple test:
const a = 4; var b = "lol"; isConst('a'); // -> true isConst('b'); // -> false
And if you declare consts in a different context, pass that context to force permission on the correct object.
Disadvantage
: this will not work on vars declared outside of the scope of objects. upside: there is absolutely no point in announcing them elsewhere. For example, declaring them in the scope of functions makes the const keyword mostly useless:
function add(a) { return ++a; } function test() { const a = 4; console.log(add(a)); } test();
Although a is constant inside test (), if you pass it to anything else, it is passed as a regular mutable value, because now it is just a βthingβ in the arguments list.
In addition, the only reason to have const is because it does not change. Thus, constantly recreating it, because you call a function that uses it more than once, means that your const should live outside the function instead, so again we are forced to put the variable in the area of ββthe object.