Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript policy on global variables / the global namespace

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'
> 
like image 792
gman Avatar asked Dec 11 '19 12:12

gman


People also ask

What is the global namespace in JavaScript?

About. The global namespace is the top space of Javascript that contains the variables. In a browser, it's known as the window.

Does JavaScript support namespace?

JavaScript does not provide namespace by default. However, we can replicate this functionality by making a global object which can contain all functions and variables.


1 Answers

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.

like image 169
snek Avatar answered Oct 10 '22 06:10

snek