Skip to content

global variable shadowed? #1026

@dosentmatter

Description

@dosentmatter

https://github.com/github/fetch/blob/d1d09fb8039b4b8c7f2f5d6c844ea72d8a3cefe6/fetch.js#L1-L5

I'm not sure if I'm reading this wrong, but it seems like the second global is shadowed by the var global declaration. After hoisting, the equivalent code is

var global; // default undefined
global =
  (typeof globalThis !== 'undefined' && globalThis) ||
  (typeof self !== 'undefined' && self) ||
  (typeof global !== 'undefined' && global) ||
  {}

Because of hoisting, the global gets evaluated as false in all environments:

(typeof global !== 'undefined' && global)
// becomes
(typeof undefined !== 'undefined' && global)
// becomes
('undefined' !== 'undefined' && undefined)
// becomes
(false &&  undefined)
// becomes
false

I think the intent was to access the global object, if it exists.

We might have to capture it to a variable, oldGlobal, first, but the hoisting of global prevents us from doing this easily.
For example, the following wouldn't work because oldGlobal and global declarations are hoisted.

var oldGlobal = global; // === undefined
var global =
  (typeof globalThis !== 'undefined' && globalThis) ||
  (typeof self !== 'undefined' && self) ||
  (typeof oldGlobal !== 'undefined' && oldGlobal) ||
  {}

The only solution I can think of that preserves the variable name, global, is to wrap the code in an IIFE to prevent hoisting above oldGlobal. The typeof global is also moved up to oldGlobal to prevent errors on environments that don't global defined.

var oldGlobal = typeof global !== 'undefined' && global
(function () {
  var global =
    (typeof globalThis !== 'undefined' && globalThis) ||
    (typeof self !== 'undefined' && self) ||
    oldGlobal ||
    {}

  // rest of the code...
})()

An alternative solution is to rename global to some other name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions