# JS Tip of the Day: Global Object vs. Global Declarations

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-global-object-vs-global-declarations/643107>\
**Category:** web dev\
**Created:** [April 29, 2020, 1:50pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-global-object-vs-global-declarations/643107 "2020-04-29T13:50:52Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [April 29, 2020, 1:50pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-global-object-vs-global-declarations/643107/1 "2020-04-29T13:50:52Z")

</div>

**Global Object vs. Global Declarations**  
Version: ES2015 (let, const, class), ES2020 (globalThis)  
Level: Intermediate

What passes as “global” in JavaScript can be quite complicated. Internally, it’s defined by something known as an _environment record_ that is made up of multiple other components. To simplify things here, we’re going to reduce those components to just two: the global object and global declarations.

At the root of it all is the global object, seen in browsers (more or less) as `window`, `global` on Node, and now more consistently represented everywhere as `globalThis`. When you refer to a variable that is not defined in any other scope but exists in the global object, you will get the value of the property of that name in the global object.

```javascript
globalThis.myProp = 'value';
console.log(myProp); // value

```

Some declarations in the top level global scope also create global properties on the global object. These include `var` and `function` declarations.

```javascript
var myVar = 'value';
function myFunc () {}

console.log('globalVar' in globalThis); // true
console.log('func' in globalThis); // true

```

Other declarations, specifically those introduced in ES2015 such as `let`, `const`, and `class`, do not create properties on the global object.

```javascript
let myLet = 'value';
const myConst = 'value';
class MyClass {}

console.log('myLet' in globalThis); // false
console.log('myConst' in globalThis); // false
console.log('MyClass' in globalThis); // false

```

While these declarations are not available in the global object, they are still global. Instead of being global object properties, they’re part of the global declarations component of global. Global declarations are global identifiers that are accessible everywhere (being global) but do not exist in the global object.

Because `var` and `functions` are also declarations, they can still impact usage of the new ES2015 declarations despite being tied to the global object. For example if you try to declare a global `let` after a global `var`, or vice versa, you’ll get an error.

```javascript
let myFirstValue = 'value';
var myFirstValue = 'value'; // SyntaxError

var mySecondValue = 'value';
let mySecondValue = 'value'; // SyntaxError

```

However, if you create a global as a global property, this does not conflict with global declarations, old or new.

```javascript
globalThis.myFirstValue = 'value';
var myFirstValue = 'value'; // Ok

globalThis.mySecondValue = 'value';
let mySecondValue = 'value'; // Ok

```

Because `var` and `function` also set global properties, their declarations would overwrite (assign) any existing global object property of the same name (`myFirstValue` above). The lexical declarations of `let`, `const`, and `class` will not, effectively giving you two global values of the same name, one as a declaration, and one as a global object (`mySecondValue`). Unqualified references to global variables by name only will use the declaration version if it exists, otherwise falling back to the global object property. Qualified references going through the global object will give you the global object property ignoring any respective declaration.

```javascript
globalThis.myFirstValue = 'prop';
var myFirstValue = 'var';

console.log(globalThis.myFirstValue); // 'var'
console.log(myFirstValue); // 'var'

globalThis.mySecondValue = 'prop';
let mySecondValue = 'let';

console.log(globalThis.mySecondValue); // 'prop'
console.log(mySecondValue); // 'let'

```

The new lexical declaration behavior of `let`, `const`, and `class` can be important in helping to prevent conflicts with global properties, especially in environments like the browser where the global object is not only global, but also a window object containing all the properties and methods for the current browser window. For example, if you want to create a `name` variable in global, before `let` or `const`, you’d have a conflict with the `window.name` property.

```javascript
var name = {};
console.log(name); // [object Object]
// (converted to string for the browser window's name)

```

Instead, using a lexical declaration with `let` or `const` means the window’s `name` property will be ignored since its only a global property and not a declaration.

```javascript
let name = {};
console.log(name); // {}
console.log(window.name); // '' (or whatever the window is named)

```

All of the global built-ins are properties only, so in using a lexical declaration with your own properties, you’ll help ensure that you won’t see any conflicts with existing built-ins.

More info:

- [var on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var)
- [let on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)
- [const on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)
