There are some things you need to consider before trying to answer this question.
For example, take the Object
constructor. It is a “Standard built-in object”.
window.status
is part of the Window
interface.
Obviously, you don’t want status
to refer to window.status
, but do you want Object
to refer to window.Object
?
The solution to your problem of it not being able to be redefined is to use a IIFE, or a module, which should be what you are doing anyways.
(() => {
var status = false;
if (!status) {
console.log('status is now false.');
}
})();
And to prevent accidentally using global variables, I would just set up your linter to warn against it. Forcing it using a solution like with (fake_global)
would not only have errors exclusively at run time, which might be not caught, but also be slower.
Specifically with ESLint, I can’t seem to find a “good” solution. Enabling browser globals allows implicit reads.
I would suggest no-implicit-globals (As you shouldn’t be polluting the global scope anyways, and it prevents the var status
not defining anything problem), and also not enabling all browser globals, only, say, window
, document
, console
, setInterval
, etc., like you said in the comments.
Look at the ESLint environments to see which ones you would like to enable. By default, things like Object
and Array
are in the global scope, but things like those listed above and atob
are not.
To see the exact list of globals, they are defined by this file in ESLint and the globals
NPM package. I would would pick from (a combination of) “es6”, “worker” or “shared-node-browser”.
The eslintrc file would have:
{
"rules": {
"no-implicit-globals": "error"
},
"globals": {
"window": "readonly",
"document": "readonly"
},
"env": {
"browser": false,
"es6": [true/false],
"worker": [true/false],
"shared-node-browser": [true/false]
}
}