Abstract
A quick review of the first ECMAScript Specification published in 1997.
From JavaScript, JScript to ECMAScript
The ECMA (European Computer Manufacturers Association) standard defines the current specification of ECMAScript a.k.a. JavaScript. Such a specification was necessary because there were on the market two version of the language: JavaScript and JScript. There were two versions of the language available at the same time because there were two web browsers competing for dominance in the browser market. As a result, the user and developer experience were affected because there was not a consistent experience and language semantics across the browsers. Designing and developing fro the Web had a big risk: some scripting code that worked well in one browser, maybe does not in the other.
The war was so evident, that even the specificaition described that moment of the history of JavaScript with this words: ‘This ECMA Standard is based on several originating technologies, the most well known being JavaScript™ (Netscape Communications) and JScript™ (Microsoft Corporation). The development of this Standard has started in November 1996’.
JavaScript was a great innovation and a key differentiator of the browser technology because it brought interactivity to the Web. Rapidly, the Netscape’s competition developed its own scripting language for the Web; Suddenly, the Web had forked into two ways of navigation, two different visions of it as well. In the middle of the struggle, Netscape opted for give to its scripting language an open nature through a thrid party organization in ordder to do not stop innovation and creativity on the Web, as well as allowing fair competition in the market. In that process, ECMA registered the name ECMAScript as trademark; since then, it is the official name for the scripting language that brought interactivity to the Web.

The First ECMAScript Standard: ES1 1997
The official document where ECMAScript is specified is the ECMA 262. The first version was published in June 1997. In the first edition of the standard, the language is defined as ‘A general purpose, cross-platform programming language’. The first specification has 110 pages and define notational conventions, data types, execution contexts, expressions, statements and the ECMAScript native objects.
With the first standard, the concept of conformance was defined: ‘A conforming implementation of ECMAScript must provide and support all the types, values, objects, properties, functions, and program syntax described in this specification’. It meant that there is a base line of the language that should be common to any implementation of the language. With that base language, it was possible for designers and developers be sure that their developments will work on any browser.
What if some browser developer would like to go beyond the first specification? It was permitted by the specification itself: ‘A conforming implementation of ECMAScript is permitted to provide additional types, values, objects, properties, and functions beyond those described in this specificaition. In particular, a conforming implementation of ECMAScript is permitted to provide properties not described in this specification, and values for those properties, for objects that are described in this specification.’ Thus, the specification from the beginning was open to innovation and evolution.
The Nature of ECMAScript
In the first page of the specificaition, JavaScript was defined as an object-oriented language intended to be executed within a host environment. Its main goal was performing computations and manipulating computational objects within such host environment. As such, JavaScript did not expect input data, and there were not computational results neither. Its nature was to be embedded in another program, the host program, and commuticate to the computational objects provided by the host through APIs.
JavaScript was also defined in 1997 as a scripting language. According to the specificaition: ‘A scripting language is a programming language that is used to manipulate, customize, and automate the facilities of an existing system.’ Thus, it was not intended as self-sufficient language since the beginning of its history, but to be embedded in other systems. A scripting language expose to professional and non-professional developers the existing functionality of the system in order to control it programmatically in an easy and lightweight manner. Althoug JavaScript was born as a Web Scripting Language, in the first specificaition it was defined with more generality just as scripting language to serve in any host environment, and the specificaition was writen with that idea.
'A scripting language is a programming language that is used to manipulate, customize, and automate the facilities of an existing system.'
Client and Server Scripting
From the beginning, JavaScript was thought as the Web scripting language. It means that it was a language intended to performs computations in the client and server host environments. First, the client side of the Web is the user agent or simply the Browser. As such, the Web Browser provides a host environment for any scripting language for client-side computations. However, due to the tied history of JavaScript with Netscape Navigation Browser, it became The scripting language of the Web.
As a web scripting language, JavaScript has the ability to deal with objects that represents windows, menus, pop-ups, text-areas, cookies and other client-side objects. Further, the host environment also provides means to attach scripting code to events. As a result, the scripting code is reactive to user interaction and there is no need for a main program. The scripting code should be shipped in the HTML itself, so when the Browser starts to parse the HMTL, it starts the parsing and execution of JavaScript scripting code. That is other way to defina a scripting language, it is always ready to be executed in any context. From the server-side of the Web, the host also provides computational objects to be processed by JavaScript like requests, responses, files and son on. Thus, the idea of a common interface for Web-based applications was already in 1997.
Language Overview
The following is a brief overview of JavaScript as defined in 1997. According to the specificaition, ECMAScript is object-based because ‘basic language and host facilities are provided by objects, and an ECMAScript program is a cluster of communicating objects.’ It sounds great, but what is an object?
An ECMAScript object is an unordered collection of properties each with 0 or more attributes which determine how each property can be used. As an example: when the attribute ReadOnly is set true for some property, then any attempt to change its state has no effect. Properties are containers for other objects, primitive values or methods. A primitive value is a member of one of the following built-in data types: Undefined, Null, Boolean, Number and String. For example: ‘undefined’ value is the only one value of ‘Undefined’ type; ‘null’ value of the ‘Null’ type; true and false values of the Boolean type and so on. Objects are members of the built-in type Object, and a method is a function associated with an object via a property.
Other built-in objects were also defined in 1997: Global, Object, Function, Array, String, Boolean, Number, Math and Date. All this features surprised me because I thought that ECMAScript was a more primitive language, and now I realize that from the beginning JavaScript had its characteristical flavor.

More about Objects
What is an Object? That is almost an existential question which is well responded in the first specificaition. A JavaScript object does not contain proper classes such as those in C++ or Java. However, JavaScript objects support constructors. A constructor creates an object by executing code that allocates storage for the object and initializes all or part of them by assigning inital values to their properties.
Constructors are functions, so they are objects too. Each constructor has a Prototype property which is used to implement prototype-based inheritance and shared properties. Objects are created by the new expression. For example, the next expression produces a new String, Boolean and Number objects:
new String("This is not a String");
new Boolean(100);
new Number(500);
A Function object was usueful to create ‘anonymous functions’ dynamically. Anonymous functions are pieces of executable code that are not bound to a name. For example, the first line of the following code creates a Function object, and the second line creates another Function object with parameter named ‘a’ and ‘b’, and the last string is the body of the function itself:
var u = new Function();
u() // returns undefined
var f = new Function('a', 'b', 'return a + b;');
f(10, 20) // returns 30
Because each constructor has a prototype property, it was possible to implement a Prototype-based inheritance. It means that every constructor has an associated prototype, and every object created by that constructor has an implicit reference to the prototype associated with its construcctor. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; that chain of prototypes is called the ‘prototype chain’.
It means that when a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, to look up for a property in the prototype chain, first is looked up in the object, if it is not there, a new look up must be done in its prototype, and so on; the search stops when the property in found or returns ‘undefined’ otherwise.
All objects that do not directly contain a particular property that their prototype contains share that property and its value. The following diagram is an excerpt from the official ES1 specificaition and it is intended to illustrate the discussion:

A Brief Review of some Aspects of the Language
By 1997, JavaScript started its journey into the specificaition process, and the preservation of the its spirit was critial. As a host language, JavaScript had its own native or built-in objects, but it could process host objects as well. Since the beginning, we can see that dual nature of JavaScript: it has a big built-in functionality, and at the same time, that functionality is extended through its access to host’s APIS. For example: Math and parseInt are built-in objects, so they belong to the language specificaition itself, but the object ‘document’ is a host object, accessible through the Brower’s DOM API.
The set of reserved words or keywords had only 16 elements, and the future reserved keywords had another 16 elements as well. I can see the old friends new, var, this, typeof, function, delete, void, etc. From the origial first set of keyword, only with has been deprecated 😿. Reading the future reserved words like switch, case, default, export or class, it was clear that the near future of JavaScript already had a path: exceptions, exception management, classes (ala JavaScript of course), modules and enumerations.
The following are the JavaScript Keywords in 1997:
break for new var
continue function return void
delete if this while
else in typeof with
The following are the future reserved words by 1997:
case debugger export super
catch default extends switch
class do finally throw
const enum import try
The set of operators included classic arithmetic, logical and relational ones; the typical bitwise operators, and the classical prefix and postfix ones. We see in the operators and keywords the influence of Java, and other languages of the C family. Here is the complete table:
= > < == <= >=
!= , ! ~ ? :
. && || ++ -- +
- * / & | ^
% << >> >>> += -=
*= /= &= |= ^= %=
<<= >>= >>>= ( ) {
} [ ] ;
Another feature of JavaScript version 1997 was automatic semicolon insertion in some cases. Also, as were mentioned above, objects had four property attributes: ReadOnly, DontEnum, DontDelete and Internal.
If the property of some object had the ReadOnly set true, then basically converted it to a const property. Although the specificaition said that in some cases, that constant property may change over time. The attribute DontEnum turned the property into a non enumerable, so it was not enumerante in a for-in loop. if DontDelete was set in true, then that property became undeletable under the delete keyword. Finally, Internal properties were, as the name suggests, internal properties of objects. Such properties have no name and were not directly accessible from JavaScript itself, i.e. ther were not exposed to the language. In the specificaition, Internal properties where written within double squared brackets as it is even today: [[ property ]]
By 1997, JavaScript had a unique global object which was created before control entered any execution context. Initially, the global object had the following built-in objects: Math, String, Date, parseInt, etc., and they had the attribute DontEnum. In such global object, host entities like the window object lived there. Other objects JavaScript had were: Function, Constructor, Prototype, Instance object, Array, String, Boolean, Number, Math and Date. JavaScript had the basic while, for, for-in and if statements.

The Execution Context
The 10th point of the first ECMAScript specificaition was dedicated to ‘execution contexts’. The section starts with the following sentence:
'When control is transferred to ECMAScript executable code, we say that control is entering an execution context. Active execution contexts logically form a stack. The top execution context on this logical stack is the running execution context.'
When JavaScript starts executing scripting code the call stack activates an execution context a.k.a stack frame. If another executable code starts its execution, a new execution context is created or activated on top of the first one, and son on. When the executable code at the top of the stack finish its execution, then that execution context is popped out of the stack and the previous execution context is now the top one.
The following illustarion is an abstract model of the execution context stack.
By 1997, JavaScript had five types of executable code:
- Global code: Source text that is outside of all function declarations.
- Eval code: Source supplied to the built-in ‘eval’ function.
- Function code: Source text tha is inside a function declaration.
- Anonymous code: Source text supplied when instantiating the ‘Function’ constructor.
- Implementation-supplied code: Source text supplied by the host when creating an implementation supplied function.
Each execution context has an associated object called the ‘variable object’. Variables declared in the source text are added as properties of the variable object. For global and eval code, functions defined in the source text are added as properties of the variable object. For function, anonymous, and implementation-supplied code, parameters are added as properties of the variable object.
Another object associated with execution contexts is the ‘scope chain’. Every execution context has one scope chain assotiated with it. When scope chain is a list of objects that are searched when binding an identifier with some value. When the control leaves the execution context, popped out of the stack, its scope chain is destroyed. The scope chain allows to have a contextualized map of identifiers in its own scope. The result of binding an identifier is always a value of type Reference with its member name component equal to the identifier string.
If the control enters an execution context for a declared function code, anonymous code or implementation-supplied code, an object called the ‘activation object’ is created and is associated with that execution context. The activation object is initialized with a property named ‘arguments’ with attribute ‘DontDelete’. This object can be accessed from inside a function with the identifier ‘arguments’. For example:
var fn = new Function('val', 'console.log(arguments); console.log(val);');
fn(46); // Prints first ==> Arguments { 0: 46 }, then Prints ==> 46
There is also a this value associated with every execution context. The this value depends on the caller and type of code being executed and is determined when control enters the execution context. The this value associated with an execution context is immutable.
When the control enters an execution context for declared function code, anonymous code or implementation-supplied code, an ‘arguments object’ is declared and initialized as follows:
- The [[Prototype]] of the arguments object is to the original Object prototype object, the one that is the initial value of Object.prototype.
- A property is created with name callee and property attributes DontEnum. The initial value of this property is the function object being executed. This allows anonymous functions to be recursive.
- A property is created with name length and property attributes DontEnum. The initial value of this property is the number of actual parameter values supplied by the caller.
- For each non-negative integer, iarg, less than the value of the length property, a property is created with name ToString(iarg) and property attributes DontEnum. The initial value of this property is the value of the corresponding actual parameter supplied by the caller. The first actual parameter value corresponds to iarg = 0, the second to iarg = 1 and so on. In the case when iarg is less than the number of formal parameters for the function object, this property shares its value with the corresponding property of the activation object. This means that changing this property changes the corresponding property of the activation object and vice versa. The value sharing mechanism depends on the implementation.
The this value
When control enters an execution context, the scope chain is created and initialized, variable instantiation is performed, and the this value is determined. The initialization of the scope chain, variable instantiation, and the determination of the this value depend on the type of code being entered. The following list illustrate the determination of this.
- For Global code: The this value is the global object itself.
- For Eval code: The this value is the same as the this value of the calling context.
- For Function and Anonymous code: The caller provides the this value. If the this value privided by the caller is not an object (including null), then the this value is the global object.
- For Implementation-Supplied code: The this value is determined just as for function and anonymous code.
The full specificaition is worth read it because it gives very well grounded knowledge about ECMAScript. For now, I can stop here and conclude this seed.
Conclusion
The first specificaition of JavaScript was an important milestone it its history. The language was liberated of verdors, opened and accessible to the world, and had defined a common standard for everyone. Today, as 2025, JavaScript is one of the technologies that powers the Web, the most important human network information ever created.