51

What is the purpose of calling

if (typeof window !== 'undefined') 

I saw it in JSPM plugin-css, and some other libraries.

YiFeng
  • 961
  • 2
  • 7
  • 15
  • for the author of that code, and as used, it's asking: "am i running in chrome or node.js?"... this nifty hybrid code works in "both" places javascript runs. – dandavis Sep 16 '15 at 03:12

2 Answers2

56

It's an idiomatic check to see if the script is being run in a web-page inside a web-browser or not.

One might assume that JavaScript only runs in web-pages as that's what it was originally designed for, but this isn't true: JavaScript is a versatile language that can also be used for writing server-side code in Node.js or IIS' Active Server Pages (since 1996!), or inside "web workers", which are scripts for web-pages that run in the background.

In a webpage, there are several intrinsic objects, such as window, other environments (like Node.js) won't have window but might have other objects like console (well, console now exists in most browsers now, but it wasn't originally).

For example, in different contexts different objects are available in the script's global scope (this list is not exhaustive):

  • In all JavaScript contexts a standard set of objects is available, such as:
    • Math and Date
    • Object, Number, Function, String, etc (objects representing built-in types), etc
  • In a web-page's script (inside <script> tags):
    • The Window (interface) is exposed as the window global object, which is also the object that is the global scope (so declaring var foo in the global scope actually creates a property window.foo!)
    • So the document global-object is actually accessing the window.document property.
  • In a Node.js server-side script:
    • As Node.js isn't a web-browser with a DOM there is no window global object nor properties like document or navigator, but instead Node.js exposes its API through global objects like:
      • console
      • process
      • exports
  • In a web-page's Web Worker script:
    • In a Web Worker there isn't a window object either, so instead the global scope is an WindowOrWorkerGlobalScope object which exposes browser-provided objects via properties like:
      • caches
      • indexedDB
      • origin
  • In IIS Active Server Pages using JScript (instead of VBScript):
    • response (for writing to the response stream)
    • request (for reading from the incoming HTTP request)
    • Application and Session (for persisting data between requests)
  • In Microsoft Windows' Shell Script Host
    • The WScript global object exposes functionality from the script host.
Dai
  • 141,631
  • 28
  • 261
  • 374
  • It still won't be equal with the string `'undefined'` though right? That's `!==` not `!=` – Blindy Sep 16 '15 at 02:55
  • 2
    @Blindy The type of the `window` object, as returned by the `typeof` operator, will be equal to the string `'undefined'`. – Maximillian Laumeister Sep 16 '15 at 02:56
  • Oh I see, that makes sense. It's the type, not the object itself – Blindy Sep 16 '15 at 02:56
  • @Blindy you're thinking of the `instanceof` operator, however `window` does not have a prototype constructor so you cannot perform any meaningful comparison with `if( window instanceof ... )`. – Dai Sep 16 '15 at 02:57
  • @dandavis my mistake, I glanced at it and saw the reference to `npm` and assumed this was related to Node. Turns out it runs within `jspm` which is different. – Dai Sep 16 '15 at 03:05
  • a minor point is that not all JS running in a browser has a window top-level object, Workers for example. – dandavis Sep 16 '15 at 03:08
  • I'm really really late to this thread, but would `if (window !== undefined)` achieve the same thing? Is the `typeof` and string equality check necessary? – SheffDoinWork Jan 26 '21 at 14:32
  • 1
    @sheffDoinWork That’s unsafe because only recently did JS engines make `undefined` immutable. `typeof` will always be safe. – Dai Jan 26 '21 at 14:43
  • 2
    @SheffDoinWork Also, in some contexts at least, directly referencing window will actually get you a "window is undefined" error. That's what I get in Windows Script Host, anyway. – trlkly Jun 29 '21 at 06:25
  • 1
    @SheffDoinWork In JS, *literal* string-equality checks are just as fast as integer equality checks, because JS strings are immutable and literals are interned by the parser before the interpreter (or JIT) even run: so it's just a simple pointer-comparison. Don't feel bad about using literal strings in JS. – Dai Jun 29 '21 at 08:01
25

This can be used to detect whether code is running in a typical browser environment (e.g. an environment with a browser DOM) or in some other JS environment since the window object exists in a typical browser JS, but does not exist in something like node.js or even a webWorker in a browser.

If the window object does not exist, then

typeof window === 'undefined'

so the code you asked about:

if (typeof window !== 'undefined') 

will execute the if block if the window object does exist as a top level variable.

In the specific code you linked, it is to keep from executing browser-targeted code that references DOM objects like document if the plugin happens to be used in a non-browser environment.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • @dandavis - where does your comment about `Workers()` come from? I didn't say anything about `Workers()`. – jfriend00 Sep 16 '15 at 02:58
  • @dandavis - I don't understand what webWorker code has to do with this question. Sorry, but I'm just not understanding your comment. This code detects the presence of a browser-like `window` object. That by itself can tell you if a DOM and it's relevant objects likely exist (vs. node.js where they do not), but it cannot tell you everything you might want to know about your environment. Some other things in the environment might require other tests (which were not the subject of the question). And, in the specific code referenced, it is used to decide if the DOM can be used. – jfriend00 Sep 16 '15 at 03:04
  • a minor point is that not all browser JS has a _window_ top-level object, Workers for example, but typical-ly you're right ;) – dandavis Sep 16 '15 at 03:05