The ECMAScript specification defines an "unique global object that is created before control enters any execution context". This global object is a standard built-in object of ECMAScript, and therefore a native object.
The spec also states:
In addition to the properties defined in this specification the global
object may have additional host defined properties. This may include a
property whose value is the global object itself; for example, in the
HTML document object model the window property of the global object is
the global object itself.
So, in web-browsers, the window object is just a convenient name for the ECMAScript global object, and therefore, the window object is a native ECMAScript object.
Did I get this correctly?
This mostly comes down to a question of what it really means to be a "native object" or a "host object". The ECMAScript specification provides fairly abstract definitions of those terms and there is plenty of room for differing interpretations of the definitions. For example, in the definition of native object, what is the word "semantics" actually talking about. Is it just the primitive object semantics (in ES specified by the [[propName]] internal properties) or does it include application level semantics of the object. The DOM window object certainly has observable application level semantics that are not defined in the ES specification, so if those semantics are considered it can't be a "native object".
The answer is probably much simpler if you look at it as a question of implementation pragmatics. A ES engine implementer probably thinks of any object that is allocated in the ES heap and managed by the ES garbage collector to be a "native ES object". A "host object" would generally be thought of something that exists external to the ES heap and that is accessed using some sort of interoperability layer such as COM, XPCOM, or the V8 embedding API. Depending upon the implementation, the DOM window object might fall into either category. This distinction is probably more relevant to both engine implementers and host providers than any of specification level distinctions.
There will likely be further definitional clarifications in the next edition of the ES specification. There is even a proposal to eliminate the "native" and "host" object terminology: http://wiki.ecmascript.org/doku.php?id=strawman:terminology . However, it isn't clear whether such definitions really have very much practical impact.
I could (and probably will) argue that the specification does not require the global object to be a native object. The spec defines a native object as:
object in an ECMAScript implementation whose semantics are fully defined by this specification rather than by the host environment.
And the definition of a host object:
object supplied by the host environment to complete the execution environment of ECMAScript.
The host object definition could certainly be applied to window, it is an object supplied by the host environment to complete the execution environment of ECMAScript. In addition, Its semantics are not fully defined by the ECMAScript specification.
There's also the case that the ECMAScript engines that run in browsers, such as V8, TraceMonkey, etc, do not create the window object. Rather, it is provided by the DOM (constructed and inheriting from DOMWindow or Window, for example).
Yes, your reasoning sounds about right. As a semi-proof, when a function is executed without explicit this ("in the global context"), its this will evaluate to window inside the function body. But this is really JSVM-specific. For example, have a look at this v8-users message (and the related discussion.) Things are a bit more complicated behind the scenes, but look approximately as you describe to the user.
Related
I'm reading DOM SPEC, and I meet the realm and I don't know what is this. According the SPEC said, it's a something of ECMA. I have learned JS, but I haven't learned about realm!
In addition, a part of content in constructing events section , To create an event using eventInterface, If I'm not mistaken eventInterface means this, but I don't found that need to give realm! Who gives the eventinterface a realm? It is chrome's blink??
From https://tc39.es/ecma262/#sec-code-realms:
Before it is evaluated, all ECMAScript code must be associated with a
realm. Conceptually, 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.
It is perfectly ok that you did not hear about realm. As a developer we can not create it, a JS engine controls realm creation when starts to execute a code.
When you create an event with new Event(), you create an object in JS and a realm is just a place where an event object is placed.
Within the Terms and Definitions section of ECMAScript 2021 Language Specification, an ordinary object is defined as:
object that has the default behaviour for the essential internal
methods that must be supported by all objects
A standard object is defined as:
object whose semantics are defined by this specification
After reading both definitions, I immediately asked myself, "Isn't the default behavior of the essential internal methods that must be supported by all objects also defined in this specification?"
I've tried searching the specification for both terms, but there are over 100 matches for 'ordinary object' and only a handful of references for 'standard object', which didn't provide additional context that made the distinction between these terms clear to me. I've also tried Google searching and none of the results seem relevant to my question.
What is the difference between an ordinary object and a standard object? What is an example of a scenario in which it is useful to distinguish between between these two types of objects?
const user = { firstname: "Jonas" };
That's an ordinary object (as it is not exotic), however it is not a standard object, as the semantics are defined by me and not by the specification. Its behavior, however, is specified (e.g. user.firstname will evaluate to "Jonas").
Yes, every ordinary object is also a standard object.
The term ordinary object is contrasted with an exotic object, which does have non-default implementations of the internal object methods. Examples of standard exotic objects are proxies, arrays and bound functions.
The term standard object (previously also known as "native object", which led to a lot of confusion) is contrasted with a host object or implementation-defined object, which are specified by a different specification (e.g. HTML5) or implemented in the engine without a formal specification. These can be functions (that are otherwise ordinary) with a host-defined call behaviour (e.g. console.log, setTimeout etc) or totally exotic objects (document.all, nodelists, etc) - see web APIs for an overview of browser-defined objects. Other environments will provide other host-defined objects.
Ordinary objects (with standard, default behavior) whose existence is governed by the host implementation or non-ECMAScript standard may be classified as either, I guess.
Just for reference, the last distinction that is relevant for this terminology discussion is between built-in objects (also builtins) and user-defined objects. The former are created by the implementation at startup, providing the environment that user code can interact with. The latter are constructed by user code at runtime. It does unfortunately become a grey area when exotic objects are constructed by native (non-user) code, these are sometimes called "built-in" as well.
See also What is the difference between native objects and host objects? and In ECMAScript, how are some of native objects also built-in?.
ES5 changed variable object(VO) to lexical environment. What's the motivation of such change since VO is already very obvious as perception?
I think variable objects are more analogous to environment records.
An Environment Record records the identifier bindings that are created
within the scope of its associated Lexical Environment.
In ES5 there are two different kinds of environment records:
Declarative environment records are used to define the effect of
ECMAScript language syntactic elements such as FunctionDeclarations,
VariableDeclarations, and Catch clauses that directly associate identifier bindings with ECMAScript language values. Object
environment records are used to define the effect of ECMAScript
elements such as Program and WithStatement that associate
identifier bindings with the properties of some object.
So the question would be why declarative environment records were introduced instead of only using object environment records just like ES3 variable objects. The difference is that declarative environment records can have immutable bindings:
In addition to the mutable bindings supported by all Environment
Records, declarative environment records also provide for immutable
bindings. An immutable binding is one where the association between an
identifier and a value may not be modified once it has been
established.
Immutable bindings don't have a direct equivalent in objects. A property can be defined as both non-configurable and non-writable, becoming immutable. However,
Creation and initialisation of immutable binding are distinct steps so
it is possible for such bindings to exist in either an initialised or
uninitialised state.
But you can't have an uninitialized property. If you define a non-configurable non-writable property with value undefined, then you won't be able to initialize it to the desired value.
I don't think it's possible to have uninitialized immutable bindings in ES5. CreateImmutableBinding is only used in Declaration Binding Instantiation and Function Definition, and in both cases it's immediately initialized with InitializeImmutableBinding.
But possibly this was done to allow uninitialized immutable bindings as extensions of the language, like the JavaScript 1.5 const. Or maybe they already had in mind ES6 const.
The same author whose ES3 article you linked wrote also about ES5 (and even linked that section there). I'll quote Mr. Soshnikov from his "Declarative environment record" section in ECMA-262-5 in detail. Chapter 3.2. Lexical environments: ECMAScript implementation:
In general case the bindings of declarative records are assumed to be stored directly at low level of the implementation (for example, in registers of a virtual machine, thus providing fast access). This is the main difference from the old activation object concept used in ES3.
That is, the specification doesn’t require (and even indirectly doesn’t recommend) to implement declarative records as simple objects which are inefficient in this case. The consequence from this fact is that declarative environment records are not assumed to be exposed directly to the user-level, which means we cannot access these bindings as e.g. properties of the record. Actually, we couldn’t also before, even in ES3 — there activation object also was inaccessible directly to a user (except though Rhino implementation which nevertheless exposed it via __parent__ property).
Potentially, declarative records allow to use complete lexical addressing technique, that is to get the direct access to needed variables without any scope chain lookup — regardless the depth of the nested scope (if the storage is fixed and unchangeable, all variable addresses can be known even at compile time). However, ES5 spec doesn’t mention this fact directly.
So once again, the main thing which we should understand why it was needed to replace old activation object concept with the declarative environment record is first of all the efficiency of the implementation.
Thus, as Brendan Eich also mentioned (the last paragraph) — the activation object implementation in ES3 was just “a bug”: “I will note that there are some real improvements in ES5, in particular to Chapter 10 which now uses declarative binding environments. ES1-3’s abuse of objects for scopes (again I’m to blame for doing so in JS in 1995, economizing on objects needed to implement the language in a big hurry) was a bug, not a feature”.
I don't think I could express this any better.
I am a JavaScript newbie. I am used to Java, thus I am trying to map two worlds in atrociously incorrect ways.
Questions:
Each Java instance runs on a JVM. What is the JVM equivalent for JavaScript?
In Java, objects occupy memory and that memory is stored on the heap. Where do JavaScript objects get stored? In other words whats the JVM's heap equivalent for JavaScript?
Each function call in Java adds a stack frame. Do JavaScript function calls do the same (i.e. add a stack)?
Java and ECMAScript are not the same language and, past generalities, have different execution models. While the JLS (Java Language Specification) is very technically precise about things like "references" and the "heap", the ECMAScript specification focuses merely on behavior.
A conforming implementation of ECMAScript must provide and support all the types, values, objects, properties, functions, and program syntax and semantics (behavior) described in this specification.
ECMAScript is executed by a "JavaScript Engine". Generally there is one "environment" per browser window; that is, each window object is the global context for at most one concurrent Program execution. This effectively means that each browser window "is a separate VM".
Each mutable object is mutable, and each object is reachable (and thus guaranteed to be alive) only as long as it is strongly referenced. The implementations certainly use "heap" memory and "references", as it is a practical/required design choice; but neither the usage of a "heap" or "references" (in this sense) is discussed in the specification.
The specification discusses the stack in terms of Execution Contexts which is composed of a logic chain.
When control is transferred to ECMAScript executable code, control is entering an execution context. Active execution contexts logically form a stack ..
What do the recent standards say about extending host objects and their prototypes? E.g. is extending NodeList with a method _forEach or Document with a method _my_query properly defined?
Will I see anything I add to Object.prototype on host objects by the standard?
How do real implementations behave with respect to the relevant standards?
Note: I am not asking whether it is a good idea to extend host objects or their prototypes (although Object.defineProperty makes things a bit easier when it comes to enumerating issues).
ECMAScript 5 does not say anything about host objects' prototype chain.
This is defined in WebIDL.
Specifically, take a look at ECMAScript bindings section, which says:
Unless otherwise specified, the [[Prototype]] internal property of
objects defined in this section is the Object prototype object.
and this, from the following section:
Each ECMAScript global environment ([ECMA-262], section 10.2.3) must
have its own unique set of each of the initial objects, created before
control enters any ECMAScript execution context associated with the
environment, but after the global object for that environment is
created. The [[Prototype]]s of all initial objects in a given global
environment must come from that same global environment.
There's even an example:
iframe.appendChild instanceof Function; // Evaluates to true
Finally, Interface Prototype Object section says (emphasis mine):
The named properties object for a given interface A must have an
internal [[Prototype]] property whose value is as follows:
If A is not declared to inherit from another interface, then the value
of the internal [[Prototype]] property of A is the Array prototype
object ([ECMA-262], section 15.4.4) if the interface was declared with
[ArrayClass], or the Object prototype object otherwise
([ECMA-262], section 15.2.4).
Otherwise, A does inherit from another interface. The value of the
internal [[Prototype]] property of A is the interface prototype object
for the inherited interface.
So now if we look at DOM Level 3, and Document interface we can see that it inherits from Node interface. Node interface does not explicitly inherit from anything else, which means it inherits from Object.prototype.
This is theory :)
In practice, not all browsers follow this behavior, although most of the recent ones certainly do.
The ECMASCRIPT5 spec states :
A web server provides a different host environment for server-side
computation including objects representing requests, clients, and
files; and mechanisms to lock and share data. By using browser-side
and server-side scripting together, it is possible to distribute
computation between the client and server while providing a customised
user interface for a Web-based application.
Each Web browser and server that supports ECMAScript supplies its own host environment,
completing the ECMAScript execution environment.
I do not think it says anything else. This can be read to mean that an implementation can conform to the spec and implement the browser objects however it wants. This has been the case in the past. It does seem logical though to apply the power of the language to the external environment and I believe that all "modern" browsers now do that.
the dom/html elements have an prototype chain as follows:
HTMLElement > Element > Node > Object
hooking in anywhere in the chain where it makes the senes is probly the best bet.