What is the 'global' object in NodeJS
Solution 1
While in browsers the global scope is the window
object, in nodeJS the global scope of a module is the module itself, so when you define a variable in the global scope of your nodeJS module, it will be local to this module.
You can read more about it in the NodeJS documentation where it says:
global
<Object> The global namespace object.
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside an Node.js module will be local to that module.
And in your code when you write:
-
console.log(this)
in an empty js file(module) it will print an empty object{}
referring to your empty module. -
console.log(this);
inside a self invoking function,this
will point to the global nodeJS scope object which contains all NodeJS common properties and methods such asrequire()
,module
,exports
,console
... -
console.log(this)
with strict mode inside a self invoking function it will printundefined
as a self invoked function doesn't have a default local scope object in Strict mode.
Solution 2
Value of this
in a node module:
this
in NodeJS global scope is the current module.exports object, not the global object. This is different from a browser where the global scope is the global window
object. Consider the following code executed in Node:
console.log(this); // logs {}
module.exports.foo = 5;
console.log(this); // log { foo:5 }
First we log an empty object because there are no values in module.exports
in this module. Then we put foo
on the module.exports
object, when we then again log this
we can see that it now logs the updated module.exports
object.
How can we access the global
object:
We can access the global
object in node using the global
keyword:
console.log(global);
The global
object exposes a variety of useful properties about the environment. Also this is the place where functions as setImmediate
and clearTimeout
are located.
Solution 3
Very interesting:
var JSON = require('circular-json');
console.log('1) ' + JSON.stringify(this, null, 2));
(function(){
console.log('2) ' + JSON.stringify(this, null, 2));
}());
(function(){
'use strict';
console.log('3) ' + JSON.stringify(this, null, 2));
}());
will produce:
1) {}
2) {
"global": "~",
"process": {
"title": "node",
"version": "v6.9.1",
"moduleLoadList": [
"Binding contextify",
"Binding natives",
"NativeModule events",
"NativeModule util",
"Binding uv",
"NativeModule buffer",
"Binding buffer",
"Binding util",
"NativeModule internal/util",
"NativeModule timers",
"Binding timer_wrap",
"NativeModule internal/linkedlist",
"NativeModule assert",
"NativeModule internal/process",
"Binding config",
"NativeModule internal/process/warning",
"NativeModule internal/process/next_tick",
"NativeModule internal/process/promises",
"NativeModule internal/process/stdio",
"Binding constants",
"NativeModule path",
"NativeModule module",
"NativeModule internal/module",
"NativeModule vm",
"NativeModule fs",
"Binding fs",
"NativeModule stream",
"NativeModule _stream_readable",
"NativeModule internal/streams/BufferList",
"NativeModule _stream_writable",
"NativeModule _stream_duplex",
"NativeModule _stream_transform",
"NativeModule _stream_passthrough",
"Binding fs_event_wrap",
"NativeModule console",
"Binding tty_wrap",
"NativeModule tty",
"NativeModule net",
"NativeModule internal/net",
"Binding cares_wrap",
"Binding tcp_wrap",
"Binding pipe_wrap",
"Binding stream_wrap",
"Binding signal_wrap"
],
"versions": {
"http_parser": "2.7.0",
"node": "6.9.1",
"v8": "5.1.281.84",
"uv": "1.9.1",
"zlib": "1.2.8",
"ares": "1.10.1-DEV",
"icu": "57.1",
"modules": "48",
"openssl": "1.0.2j"
},
"arch": "x64",
"platform": "linux",
"release": {
"name": "node",
"lts": "Boron",
"sourceUrl": "https://nodejs.org/download/release/v6.9.1/node-v6.9.1.tar.gz",
"headersUrl": "https://nodejs.org/download/release/v6.9.1/node-v6.9.1-headers.tar.gz"
},
"argv": [
"/usr/local/bin/node",
"/home/froth/freelancer-projects/thistest.js"
],
"execArgv": [],
"env": {
"NVM_DIR": "/home/froth/.nvm",
"LD_LIBRARY_PATH": "/opt/opencascade/lib",
"CSF_UnitsDefinition": "/opt/opencascade/src/UnitsAPI/Units.dat",
"CSF_GraphicShr": "/opt/opencascade/lib/libTKOpenGl.so",
"CSF_EXCEPTION_PROMPT": "1",
"LANG": "de_DE.UTF-8",
"PROFILEHOME": "",
"DISPLAY": ":0",
"SHELL_SESSION_ID": "09b6f0f3b1d94c5f8aba3f8022075677",
"NODE_PATH": "/usr/lib/node_modules",
"COLORTERM": "truecolor",
"NVM_CD_FLAGS": "",
"MOZ_PLUGIN_PATH": "/usr/lib/mozilla/plugins",
"CSF_IGESDefaults": "/opt/opencascade/src/XSTEPResource",
"CSF_XCAFDefaults": "/opt/opencascade/src/StdResource",
"XDG_VTNR": "1",
"PAM_KWALLET5_LOGIN": "/tmp/kwallet5_froth.socket",
"CSF_STEPDefaults": "/opt/opencascade/src/XSTEPResource",
"XDG_SESSION_ID": "c2",
"CSF_XSMessage": "/opt/opencascade/src/XSMessage",
"USER": "froth",
"DESKTOP_SESSION": "/usr/share/xsessions/awesome",
"GTK2_RC_FILES": "/home/froth/.gtkrc-2.0",
"PWD": "/home/froth/freelancer-projects",
"HOME": "/home/froth",
"XDG_SESSION_TYPE": "x11",
"CSF_PluginDefaults": "/opt/opencascade/src/StdResource",
"XDG_DATA_DIRS": "/usr/local/share/:/usr/share/:/var/lib/snapd/desktop",
"NVM_IOJS_ORG_MIRROR": "https://iojs.org/dist",
"KONSOLE_DBUS_SESSION": "/Sessions/1",
"XDG_SESSION_DESKTOP": "",
"CSF_StandardDefaults": "/opt/opencascade/src/StdResource",
"CSF_StandardLiteDefaults": "/opt/opencascade/src/StdResource",
"MMGT_CLEAR": "1",
"KONSOLE_DBUS_WINDOW": "/Windows/1",
"CSF_UnitsLexicon": "/opt/opencascade/src/UnitsAPI/Lexi_Expr.dat",
"GTK_MODULES": "canberra-gtk-module",
"MAIL": "/var/spool/mail/froth",
"NVM_RC_VERSION": "",
"CSF_XmlOcafResource": "/opt/opencascade/src/XmlOcafResource",
"TERM": "xterm-256color",
"SHELL": "/bin/bash",
"KONSOLE_DBUS_SERVICE": ":1.23",
"XDG_SESSION_CLASS": "user",
"XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0",
"XDG_CURRENT_DESKTOP": "",
"QT_LINUX_ACCESSIBILITY_ALWAYS_ON": "1",
"KONSOLE_PROFILE_NAME": "Shell",
"CASROOT": "/opt/opencascade",
"NVM_NODEJS_ORG_MIRROR": "https://nodejs.org/dist",
"COLORFGBG": "15;0",
"XDG_SEAT": "seat0",
"SHLVL": "2",
"LANGUAGE": "",
"WINDOWID": "29360134",
"LOGNAME": "froth",
"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus",
"XDG_RUNTIME_DIR": "/run/user/1000",
"CSF_MDTVTexturesDirectory": "/opt/opencascade/src/Textures",
"XAUTHORITY": "/home/froth/.Xauthority",
"XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session1",
"PATH": "/home/froth/.gem/ruby/2.3.0/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/snap/bin:/usr/lib/jvm/default/bin:/opt/opencascade/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl",
"CSF_LANGUAGE": "us",
"CSF_SHMessage": "/opt/opencascade/src/SHMessage",
"OLDPWD": "/home/froth",
"_": "/usr/local/bin/node"
},
"pid": 4658,
"features": {
"debug": false,
"uv": true,
"ipv6": true,
"tls_npn": true,
"tls_alpn": true,
"tls_sni": true,
"tls_ocsp": true,
"tls": true
},
"_needImmediateCallback": false,
"execPath": "/usr/local/bin/node",
"debugPort": 5858,
"_events": {
"SIGWINCH": [
null,
null
]
},
"_eventsCount": 4,
"domain": null,
"_exiting": false,
"config": {
"target_defaults": {
"cflags": [],
"default_configuration": "Release",
"defines": [],
"include_dirs": [],
"libraries": []
},
"variables": {
"asan": 0,
"debug_devtools": "node",
"force_dynamic_crt": 0,
"gas_version": "2.23",
"host_arch": "x64",
"icu_data_file": "icudt57l.dat",
"icu_data_in": "../../deps/icu-small/source/data/in/icudt57l.dat",
"icu_endianness": "l",
"icu_gyp_path": "tools/icu/icu-generic.gyp",
"icu_locales": "en,root",
"icu_path": "deps/icu-small",
"icu_small": true,
"icu_ver_major": "57",
"node_byteorder": "little",
"node_enable_d8": false,
"node_enable_v8_vtunejit": false,
"node_install_npm": true,
"node_module_version": 48,
"node_no_browser_globals": false,
"node_prefix": "/",
"node_release_urlbase": "https://nodejs.org/download/release/",
"node_shared": false,
"node_shared_cares": false,
"node_shared_http_parser": false,
"node_shared_libuv": false,
"node_shared_openssl": false,
"node_shared_zlib": false,
"node_tag": "",
"node_use_bundled_v8": true,
"node_use_dtrace": false,
"node_use_etw": false,
"node_use_lttng": false,
"node_use_openssl": true,
"node_use_perfctr": false,
"node_use_v8_platform": true,
"openssl_fips": "",
"openssl_no_asm": 0,
"shlib_suffix": "so.48",
"target_arch": "x64",
"uv_parent_path": "/deps/uv/",
"uv_use_dtrace": false,
"v8_enable_gdbjit": 0,
"v8_enable_i18n_support": 1,
"v8_inspector": true,
"v8_no_strict_aliasing": 1,
"v8_optimized_debug": 0,
"v8_random_seed": 0,
"v8_use_snapshot": true,
"want_separate_host_toolset": 0
}
},
"stdout": {
"connecting": false,
"_hadError": false,
"_handle": {
"bytesRead": 0,
"_externalStream": {},
"fd": 9,
"writeQueueSize": 0,
"owner": "~process~stdout"
},
"_parent": null,
"_host": null,
"_readableState": {
"objectMode": false,
"highWaterMark": 16384,
"buffer": {
"head": null,
"tail": null,
"length": 0
},
"length": 0,
"pipes": null,
"pipesCount": 0,
"flowing": null,
"ended": false,
"endEmitted": false,
"reading": false,
"sync": true,
"needReadable": false,
"emittedReadable": false,
"readableListening": false,
"resumeScheduled": false,
"defaultEncoding": "utf8",
"ranOut": false,
"awaitDrain": 0,
"readingMore": false,
"decoder": null,
"encoding": null
},
"readable": false,
"domain": null,
"_events": {},
"_eventsCount": 3,
"_writableState": {
"objectMode": false,
"highWaterMark": 16384,
"needDrain": false,
"ending": false,
"ended": false,
"finished": false,
"decodeStrings": false,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": false,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 1,
"prefinished": false,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree": {
"next": null,
"entry": null
}
},
"writable": true,
"allowHalfOpen": false,
"destroyed": false,
"_bytesDispatched": 6,
"_sockname": null,
"_writev": null,
"_pendingData": null,
"_pendingEncoding": "",
"server": null,
"_server": null,
"columns": 84,
"rows": 84,
"_type": "tty",
"fd": 1,
"_isStdio": true
},
"stderr": {
"connecting": false,
"_hadError": false,
"_handle": {
"bytesRead": 0,
"_externalStream": {},
"fd": 11,
"writeQueueSize": 0,
"owner": "~process~stderr"
},
"_parent": null,
"_host": null,
"_readableState": {
"objectMode": false,
"highWaterMark": 16384,
"buffer": {
"head": null,
"tail": null,
"length": 0
},
"length": 0,
"pipes": null,
"pipesCount": 0,
"flowing": null,
"ended": false,
"endEmitted": false,
"reading": false,
"sync": true,
"needReadable": false,
"emittedReadable": false,
"readableListening": false,
"resumeScheduled": false,
"defaultEncoding": "utf8",
"ranOut": false,
"awaitDrain": 0,
"readingMore": false,
"decoder": null,
"encoding": null
},
"readable": false,
"domain": null,
"_events": {},
"_eventsCount": 3,
"_writableState": {
"objectMode": false,
"highWaterMark": 16384,
"needDrain": false,
"ending": false,
"ended": false,
"finished": false,
"decodeStrings": false,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": true,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 0,
"prefinished": false,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree": {
"next": null,
"entry": null
}
},
"writable": true,
"allowHalfOpen": false,
"destroyed": false,
"_bytesDispatched": 0,
"_sockname": null,
"_writev": null,
"_pendingData": null,
"_pendingEncoding": "",
"server": null,
"_server": null,
"columns": 84,
"rows": 84,
"_type": "tty",
"fd": 2,
"_isStdio": true
},
"stdin": {
"connecting": false,
"_hadError": false,
"_handle": {
"bytesRead": 0,
"_externalStream": {},
"fd": 12,
"writeQueueSize": 0,
"owner": "~process~stdin",
"reading": false
},
"_parent": null,
"_host": null,
"_readableState": {
"objectMode": false,
"highWaterMark": 0,
"buffer": {
"head": null,
"tail": null,
"length": 0
},
"length": 0,
"pipes": null,
"pipesCount": 0,
"flowing": null,
"ended": false,
"endEmitted": false,
"reading": false,
"sync": false,
"needReadable": true,
"emittedReadable": false,
"readableListening": false,
"resumeScheduled": false,
"defaultEncoding": "utf8",
"ranOut": false,
"awaitDrain": 0,
"readingMore": false,
"decoder": null,
"encoding": null
},
"readable": true,
"domain": null,
"_events": {},
"_eventsCount": 4,
"_writableState": {
"objectMode": false,
"highWaterMark": 0,
"needDrain": false,
"ending": false,
"ended": false,
"finished": false,
"decodeStrings": false,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": true,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 0,
"prefinished": false,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree": {
"next": null,
"entry": null
}
},
"writable": false,
"allowHalfOpen": false,
"destroyed": false,
"_bytesDispatched": 0,
"_sockname": null,
"_writev": null,
"_pendingData": null,
"_pendingEncoding": "",
"server": null,
"_server": null,
"isRaw": false,
"isTTY": true,
"fd": 0
},
"argv0": "node",
"mainModule": {
"id": ".",
"exports": {},
"parent": null,
"filename": "/home/froth/freelancer-projects/thistest.js",
"loaded": false,
"children": [
{
"id": "/home/froth/freelancer-projects/node_modules/circular-json/build/circular-json.node.js",
"exports": {},
"parent": "~process~mainModule",
"filename": "/home/froth/freelancer-projects/node_modules/circular-json/build/circular-json.node.js",
"loaded": true,
"children": [],
"paths": [
"/home/froth/freelancer-projects/node_modules/circular-json/build/node_modules",
"/home/froth/freelancer-projects/node_modules/circular-json/node_modules",
"/home/froth/freelancer-projects/node_modules",
"/home/froth/node_modules",
"/home/node_modules",
"/node_modules"
]
}
],
"paths": [
"/home/froth/freelancer-projects/node_modules",
"/home/froth/node_modules",
"/home/node_modules",
"/node_modules"
]
}
},
"console": {}
}
3) undefined
In 3)
this is undefined as it is not autoboxed to an object in strict mode. That means that there is no root object in this context. If you do not use strict mode then your code is boxed by a parent scope.As you can see in the output, within nodejs there is lot of information about node internal stuff.
In 1)
the output is an empty object because in the top-level code in a node module, this is the equivalent to module.exports and module.exports is empty in this example.
Solution 4
To start with documentation on Global context in node environment
In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node.JS this is different. The top-level scope is not the global scope; var something inside a Node.JS module will be local to that module.
Each JS file is treated as a module. Node automatically wraps the code of a JS file in a self IIFE with exports, require, module, __filename, __dirname
as parameters to the function.
Below is the screenshot of execution context using node-debug
If you run the below code, prints true
which means this
refers to exports
in node.js. Best explained in this answer.
console.log(this === exports);
Which means at execution the code is wrapped something similar as below in Node.js separating your code from global context using a wrapper function context or IIFE technique hypothetically.
var context = (function (exports, require, module, __filename, __dirname) {
console.log(this) //This is my code
});
/** hypothetical module wrapper code **/
var module = {exports:{}};
context.apply(module.exports, [module.exports, require, module, "FILE_NAME", "DIR_NAME"]);
Answer to the next point refer this documentation completely:
A function's
this
keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.
so when you execute this code
(function(){
console.log(this);
}());
prints the global
object and in use strict
mode prints undefined
Remember:
In browser the function is not wrapped by IIFE wrapper function context as done in Node.JS, it's directly executed on window
object. Hence the calling context varies for Node.JS and Browser.
Also read this article.
Solution 5
Here i want to highlight one property of global !
What you put there is accessible also directly
(make sure to check the Property title and section)
Before bringing the property! Let's define global again!
global is a language keyword specific to nodejs and reference The global namespace object
As it was already described on other answers! The top scope in a module! Is not global! And limited to only that module!
So when you declare a variable in one module you can't access it in another!
https://nodejs.org/api/globals.html#globals_global
The global namespace is accessible everywhere in a given process! In all modules! That's include your own module and third party modules!
console Logging global in node repl will give this:
Welcome to Node.js v13.14.0.
Type ".help" for more information.
> console.log(global)
<ref *1> Object [global] {
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
},
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
}
}
undefined
The property: What you put there is accessible also directly
What i wanted to bring is this! I get to notice this when i was exploring laravel-mix code source!
If you set something on the global object! as like
global.Hola = { print: () => console.log("Hola") };
. Then you can access the variable by it's name directly any where in the project code (multiple files [modules] & Whole node process code)! MeaningHola.print()
in place ofglobal.Hola.print()
!
Here a node repl screenshot for the example above:
> global.Hola = { print: () => console.log('Hola') }
{ print: [Function: print] }
> Hola.print()
Hola
undefined
Nice property ! That's the global namespace!
You can notice the methods like clearInteraval
, clearTimeout
, setInterval
, setTimeout
, ... are defined there! And we used to access them directly by there name!
Laravel mix example
Here some examples from laravel-mix code source! Where it use that!
If you open this file: https://github.com/JeffreyWay/laravel-mix/blob/master/src/components/ComponentRegistrar.js
You notice in the import section there is no! Mix
variable neither Config
!
But they are used and part of the code! I was like: what the heck
!
Imort code:
let Assert = require('../Assert');
let Dependencies = require('../Dependencies');
let mergeWebpackConfig = require('../builder/MergeWebpackConfig');
On line 68 : (link here) you can see the usage of Mix
class variable!
And same thing for Config
at line 178 (link here)
When i first got to see it! And get to check the import section! And using github reference feature (came with nothing)! I was What the heck
!
Later on when i checked the Mix.js file! And class! I found the code that set them! I got the intuition and googled after!
Conflicts and Why one would want to use the global namespace
A problem to setting globals is overriding and conflicts! Which leads to bugs and unexpected behaviors, up to a total crash! If modules start to use it without thoughts! One module will screw it for another! Like when using a third party module! Imagine module request
will set Config var! And you set it too! Or even another third party module! And they are all dependent on it! One will screw it for the other module!
So simply put! We should not use globals! No no! And yes!
It all depends!
It's preferable for a module to not do! That way the module is completly isolated! And it's more robust! Generally setting the variable in a certain module! And importing it each time! Using dependency injection ...etc
In many cases however it's more flexible to use the global namespace!
You can do so and not worry! If you are building a server! Config object can go on the global! A command line Interface tool or script! Some process that run directly!
Generally don't use the global scope when you are building a module! A package! A library! A component! Which gonna be reusable! (Reusable cross projects! no global scope! isolate it)!
Laravel mix for instance is a package that is used to generate webpack config! That get to run as a cli tool and process!
However if the Config variable for example was also set by Webpack or some of the community plugins or loaders! Then problems can occure due to overriding!
Something simple could make it safer is to add a domain in the naming! For instance Mix_Config
!
Arnab Das
Updated on December 16, 2021Comments
-
Arnab Das over 2 years
I've just seen a weird behaviour of the
this
keyword in NodeJS environment. I'm listing them with code. I've run this codes withNodeJS v6.x
, with a singleJavaScript
file.While testing with one line of code as follows, whether with or without the
'use strict'
statement, this points to an empty object{}
.console.log(this)
But, when I'm running the statement within a self executing function like,
(function(){ console.log(this); }());
It's printing a really big object. Seems to me the Global execution context object created by
NodeJS
environment.And while executing the above function with a
'use strict'
statement, expectedly it's printingundefined
(function(){ 'use strict'; console.log(this); }());
But, while working with browser (I've tested only with
Chrome
), the first three examples yield thewindow
object and the last one gaveundefined
as expected.The behaviour of the browser is quite understandable. But, in case of
NodeJS
, does it not create the execution context, until I'm wrapping inside a function?So, most of the code in
NodeJS
runs with an empty globalobject
? -
brian over 5 yearsThis was the answer I actually needed.
-
Panu Logic about 4 years"... will print an empty object {} referring to your empty module." That is somewhat misleading. A better answer is by Willem van der Veen below. The value of this which is { } does NOT refer to the "module" but to the current "module.exports" -object. The module (-object) itself is not "empty" since it has the property 'exports' whose value is an Object with no local properties, sometimes referred to as an "empty object". But even such an "empty" object {} is really not "empty" because it does have inherited properties such as its method "toString()".
-
Panu Logic about 4 yearsThis is the most accurate answer I would say, although the title of the answer is about a slightly different question ("Value of this in a node module...") than originally asked. Still most helpful for understanding it all emphasizing that 'this' and 'global object' are two different things not only in Node.js but in JavaScript in general
-
cнŝdk about 4 years@PanuLogic the statement is totally
logic
, if you would like to be logic and it's not misleading, it's the facts here, and the properties you are talking about are always inherited by all objects, it's not worthy mentionning them, by the way it's the Docs spécification. And we are here talking aboutthis
or Global object in nodejs and not Javascriptobject
definition so we should focus on that point :) -
Joseph almost 4 yearsIf you want a reference to the global object that works in any context, you can read
this
from a directly-called function.const global = (function() {return this})();
. This evaluates towindow
in the browser,self
in a service worker andglobal
in nodejs. -
hane Smitter almost 2 yearsThe major con of accessing the 'global scope' inside a traditional function as Joseph has stated is that you will get undefined when using
strict mode
. I recommend usingglobalThis
property. In this way, you can always reference the global object in a consistent manner without having to know which environment the code is being run in (such as in browser, web worker, Nodejs, e.t.c ) or the current execution context (scope)