Sources:
A realm is the world/ecosystem in which a JavaScript program lives. It includes different elements that JavaScript programs must have in order to exist within it.
If I want to create a realm, i must provide the above components, for any javascript program to be able to run in it
In javascript, we have different scopes.
let x = 1;
let innerScope = () => {
let y = x + 2; // we can access x from the outer scope
};
let z = x + y; // Uncaught ReferenceError: y is not defined
in the above example, we are able to declare a scope called innerScope, in which we can define variables that belong to the scope (i.e. y)
and that cannot be accessed outside of the scope.
It is possible as well that this whole javascript program itself is an inner scope within some larger outer scope. maybe it is imported from a different file or something (need to verify if this is a correct example) in which case the file importing it will be a higher-level scope.
If we keep going up and up in scope, we will eventually get to the top-level declaration - the outer-most scope. This is the global execution environment.
In this scope, or global execution environment, we can declare new variables. Based on how we declare new variables in the top-level scope, we can populate new definitions in two different places:
let, class, module, import, and/or function in the global execution environment to declare stufflet, const, class, e.t.c.) are blocked-scoped, and do not become properties of the global objectwindow or globalThis in Node.js)var, function, async function, function*, async function*window, globalThis, e.t.c.)strict mode or if the code is being run as a module.
Key Takeaway: A realm provides the javascript program with its own single global execution environment
The global object is referenced as window for browsers and global for NodeJS environments; in both, globalThis can also be used.
After having a proper environment in which javascript programs can execute, they also need to be able to perform advanced operations, including but not limited to platform based ones. The global object provides access to built-ins such as different intrinsics, objects, APIs, e.t.c. (whether platform specific or not)
Some non-platform based intrinsic objects exposed by the global object:
undefined, Infinity, e.t.c.)eval, parseInt, e.t.c.)Boolean, Date, e.t.c.)JSON, Math, e.t.c.)Some browser-specific APIs exposed by the global object:
fetch, alert, document, the DOM, e.t.c.Any platform specific objects and APIs are accessible via the global object along with all intrinsic objects and new properties declared by code.
The last thing that can be associated with a realm is the JavaScript code that runs within the execution environment of that realm.
Any changes/alternations/updates to the execution environment, the global object or anything that is derived under a realm, is also associated exclusively with that realm.
if two iframe realms are of the same origin (child of the same agent),
contentWindow (i believe this is because they share the same event loop? maybe?)you can achieve same origin realms using iframe, frame, object, embed and open
if they are of different origins (e.g. the top main realm and a service worker (i.e. web worker) are of different origins)
postMessage() asynchronous APIan example in the browser implementation of the ecmascript spec is web workers and service workers they are cross-origin realms to all other realms in the web app, such as the "top" realm or "window",
Each realm has its own unique identity with a unique global object, global execution environment, and each realm has its own set of intrinsic objects and platform based APIs. Primitives, however, are identical across realms (i guess they are shared across realms even though they are defined within realms i think?)
<html>
<head></head>
<body>
<iframe id="some_iframe"></iframe>
</body>
</html>
window === some_iframe.contentWindow // false
window.fetch === some_iframe.contentWindow.fetch // false
window.Array === some_iframe.contentWindow.Array // false
// Primitives
window.Infinity === some_iframe.contentWindow.Infinity // true