What is the purpose of passing WindowProxy as the global this value? - javascript

Background
The HTML spec introduces the concept of the WindowProxy.
It says:
A WindowProxy is an exotic object that wraps a Window ordinary object,
indirecting most operations through to the wrapped object. Each
browsing context has an associated WindowProxy object. When the
browsing context is navigated, the Window object wrapped by the
browsing context's associated WindowProxy object is changed.
The WindowProxy platform object is created when the browsing context is created by the host, as defined in ECMAScript's InitializeHostDefinedRealm (step 8). It is directly set to be the global this value.
At that same point, the Window object is created, set to be the global object.
Through the ECMAScript spec, we see that whenever a lookup of an identifier happens, it first searches the environment record of the current execution context, and if not found continues out all the way out to the Global Environment Record, which in turn looks for the identifier on the global object.
As far as I can see, this set of operations never uses the global this value.
Questions
Are there any operations in ECMAScript that use the global this value? If so, which?
How exactly does setting the global this value to WindowProxy result in the desired proxy behavior?
Edit
This StackOverflow question answers the high-level purpose of WindowProxy. My question above is related to the ECMAScript spec and how exactly the standard built-in operations get delegated to the WindowProxy object, by virtue of it being the global this value.
Article with some interesting, but vague, information not related to the ECMAScript spec.

I'm not sure if this is the only reason, but this at least allows to have the built-ins bound to the WindowProxy instead of on the Window, which may not be unique to the browsing-context.
This is done in https://tc39.es/ecma262/#sec-global-environment-records
A Global Environment Record is logically a single record but it is specified as a composite encapsulating an Object Environment Record and a Declarative Environment Record. The Object Environment Record has as its base object the global object of the associated Realm Record. This global object is the value returned by the Global Environment Record's GetThisBinding concrete method. The Object Environment Record component of a Global Environment Record contains the bindings for all built-in globals (clause 19) and all bindings introduced by a FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, or VariableStatement contained in global code. The bindings for all other ECMAScript declarations in global code are contained in the Declarative Environment Record component of the Global Environment Record.
You can see an example where this is observable in this JSFiddle* where we store the built-in function eval (hereafter storedEval) originating from a same-origin <iframe>.
From the <iframe>'s context we declare a global variable window.foo = "first frame".
Calling storedEval("this.foo") from the parent document we get back the string "first frame". This means that our storedEval function correctly is bound with the <iframe>'s context.
Then we navigate the <iframe> to a new document. At this point, the global object has been replaced, this.foo is undefined in the new <iframe> context.
Now, if we call again storedEval("this.foo") from the parent document, we also get undefined. And if we then set window.foo in the new <iframe> document, we'd get that new value.
This is because the built-in eval is bound to the WindowProxy, and not to the global Window object. Failing to do so, we'd keep a reference of the previous Window, even after its document has been navigated away.
* The example is outsourced because StackSnippet's null-orgined iframes don't allow cross-access, even from srcdoc

Related

Why every execution context has Realm?

I'm reading ECMAScript 2023.
It say all execution contexts has "Realm" state component.
And it describes,
a realm consists of a set of intrinsic objects, an ECMAScript global environment, all of the ECMAScript code that is loaded within the scope of that global environment, and other associated state and resources.
I understand realm is for global environment like window(browser), global(node).
And I understand "Global Environment Records" already define global environment once on first code evaluation.
I wonder why a Realm for a execution context is needed.
I'm reading https://tc39.es/ecma262/#sec-execution-contexts.
You can find the current Realm record as "the value of the Realm component of the running execution context".
That term is referenced multiple times across the specification, mostly for bookkeeping to carry-over the value, but in the end to lookup intrinsic prototypes or cached template strings from the current realm.

Global "window" object

The global window object stores properties specific to the environment (for example, window.innerHeight).
But if we print window to the console, we will see the properties highlighted in a different color.
These include Array, Object, and so on, although i thought they are internal objects.
I have a few questions:
What are these "implicit" properties?
Where do JS boundaries end and environment begin?
Can I refer to Array in Node.js, for example?
Thank you.
In the early days of Javascript, there was one master global symbol and everything that was available in the global scope whether it was part of the language itself or part of the browser environment was a property of that master global.
In the browser, that master global is the window object. Thus, you see many things on the window object that are available globally like the Array constructor.
I would guess that this is a side effect of that fact that Javascript was first designed to run in a browser and was not initially a completely stand-alone language with a stand-alone specification.
More recent revisions to the language specification are not adding some new things to the window object any more. For example, when you declare an ES6 class such as:
class Foo {
constructor(greeting) {
this.greeting = greeting;
}
}
You will not find Foo on the window object even though it may be globally available in the browser.
As others have said, the color difference in the debug output has to do with whether the symbols are enumerable or not which is a technical distinction on whether the property shows up in something like Object.keys() or a for/in loop. The property is still there and is accessible either way.

Is the global execution context the same as the global object in JavaScript?

As I understand it, every time a JavaScript program begins running, the engine first creates an execution context, pushes this execution context into the call stack/execution stack, and then it creates a global object (window in the browser and global in Node) as well.
To create the execution context, the engine first goes through the creation phase, where it allocates space in memory for entire function definitions and variable declarations (hoisting). It maintains a reference to the outer scope (this creates the scope chain, but in the global execution context there isn't anything above it), and it also creates the this property within the execution context and sets it to the window object in the browser and module.exports in Node. Lastly, the engine then goes through the execution phase, where it executes the code line by line and assigns a value to each variable.
Am I right in differentiating the global execution context creation from the creation of the global object itself? I view both of them as operations that happen side by side but are not the exact same thing.
Yes, it's fair to say that the global context and the global object are separate concepts. One illustrating distinction is the this binding: a context defines what this refers to (in case of the global context: to the global object); whereas the global object has no property named "this".
At the same time, global context and global object are somewhat coupled insofar as local variables in the former are properties on the latter.
Note that "execution context" is mostly an abstract concept, that means an engine only has to behave "as if" it did what the spec describes. Chances are that high-performance engines will take certain shortcuts (e.g., optimized code might keep some local variables in registers or on the machine stack, never putting them into any context at all).

V8 / JS runtime: how are JavaScript window functions available without prefix "window"

I don't know much about the JS console but I'm moving into command line programming and it would be good to know my native environment before I start using shell/node in a foreign one
My guess is that all command line statements are invoked with (window) eval(/* whatever user typed before hitting enter/*) but this seems like horrible practice. The context is definitely bound as "Window" if I console.log(this) but I'm not sure why / how
It's almost like the user cd'd into the window object to set it as the context
All JavaScript has a global scope. In the browser, the global scope is called "window" and it is a reference to the window object. In node, it is called "global" and refers to the global JS namespace in node.
The "window" global in a browser has a bunch of properties on it. Things like "console" or "location". When you want to talk to those pieces of code, you can optionally prefix the call with "window.". Example: to log something to the console you can type:
window.console.log("HELLO");
or you can leave the "window." off of the call, like such:
console.log("HELLO");
The global "window" object in the browser is the only optional object on the page. Any time you see a reference to a variable that wasn't declared using "var" (or "let" and "const" in ES6), that means that the variable is just a property on the global object.

Is there a defined name for the execution context that encapsulates all others in JavaScript?

Is there a defined name for the execution context that encapsulates all others in JavaScript?
For example is it called the "global execution context". That phrase is not mentioned in the ES6 spec as far as I can find.
It's called "the global environment" as per the ES5 spec (or see the equivalent section of the ES6 spec):
The global environment is a unique Lexical Environment which is created before any ECMAScript code is executed. The global environment’s Environment Record is an object environment record whose binding object is the global object (15.1). The global environment’s outer environment reference is null.
Or perhaps you are looking for the "initial global execution context", whose lexical and variable environment are references to the global environment.
I don't believe there's any term more specific than simply "global environment" or "global environment record" (to draw a distinction with its binding object) which is used several places in the ES6 pecification such as §8.1 and §8.1.14 (draft spec, those section numbers may drift).

Categories

Resources