Today I ran into an issue that top
is a pre-existing global variable.
const left = 1;
const right = 2;
const top = 3;
const bottom = 4;
console.log(left, right, top, bottom);
result:
Uncaught SyntaxError: Identifier 'top' has already been declared
I think I've just been lucky until today that most of the time my usage of a variable called top
was inside a function.
How much do I need to worry about browsers adding new global variables that will break code in the future? It seems like until es6 import pretty much all browser libraries used global variables unless they had a build step. But, looking at the top
example it seems like browser could add new unsettable global variables at anytime and therefore they should be avoided at all costs. I see some variables things like HTMLElement
are assignable.
console.log(HTMLElement);
HTMLElement = 'foo';
console.log(HTMLElement);
result:
function HTMLElement() { [native code] }
foo
Is top
some legacy thing but browser specs promise not to do more of that in the future? Like I can't assign window
const window = 'foo';
console.log(window);
result:
SyntaxError: Identifier 'window' has already been declared
but I can assign process
in node
Welcome to Node.js v12.6.0.
Type ".help" for more information.
> process
process {
version: 'v12.6.0',
versions: {
node: '12.6.0',
...
}
> process = 'foo'
'foo'
> process
'foo'
>
How much do I need to worry about browsers adding new global variables that will break code in the future?
You shouldn't worry about it. New features for JS and HTML are tested extensively. Browsers will generally deploy code that watches for incompatibilities with planned APIs to determine if they will be safe to ship. (For example if a browser wants to add globalThis.foo
, it might deploy a counter that increments every time code accesses or assigns to globalThis.foo
to understand if it's already being used for something else). In addition, developer previews of browsers allow developers to catch possible issues before they get too far. You might find this interesting: https://developers.google.com/web/updates/2018/03/smooshgate.
All that being said, I still wouldn't suggest you go around creating lots of globals, it's not the most fantastic pattern.
Is top some legacy thing but browser specs promise not to do more of that in the future? Like I can't assign window
It is indeed legacy, though I don't know of any such promises. The HTML standard defines window.top
as follows (from https://html.spec.whatwg.org/#the-window-object):
[LegacyUnforgeable] readonly attribute WindowProxy? top;
[LegacyUnforgeable]
means the property top
is created on window
with the property attribute configurable
set to false
. Global declarations that shadow non-configurable properties will fail because they cannot change the value.
but I can assign process in node
This is because process
in Node.js is a configurable property.
> Object.getOwnPropertyDescriptor(globalThis, 'process')
{
get: [Function: get],
set: [Function: set],
enumerable: false,
configurable: true
}
As a last note, there is a difference between assignments and declarations. You can still assign to non-configurable properties as long as they are writable or provide a setter.