What’s ECMAScript?
I’ve sometimes been very confused about the differences and relationship between ECMAScript and Javascript, so let’s go through some concepts to clear this topic.
Ecma International
An organization that creates standards for technologies.
To illustrate an example of “standard” (though not one created by Ecma), think of all the keyboards you have ever used. Did the vast majority have letters in the same order, and a space bar, an Enter key, arrow keys, with numbers displayed in a row at the top? This is because most keyboard manufacturers base their keyboard design on the QWERTY layout standard.
A scripting language
A programming language designed specifically for acting on an existing entity or system
For a general idea of what makes a programming language a scripting language, consider the commands “walk”, “run”, and “jump.” These actions require something to carry them out, perhaps a person, a dog, or a video game character. Without an actor to perform these commands, “walk”, “run”, and “jump” wouldn’t make sense. This set of actions is analogous to a scripting language that focuses on manipulating an external entity.
ECMAScript
The specification defined in ECMA-262 for creating a general purpose scripting language.
Synonym: ECMAScript specification
ECMAScript is a standard for scripting languages built by ECMA international.
ECMAScript provides the rules, details, and guidelines that a scripting language must observe to be considered ECMAScript compliant.
JavaScript
A general purpose scripting language that conforms to the ECMAScript specification.
JavaScript is a programming language and ECMAScript is the specification it’s based on. By reading the ECMAScript specification, you learn how to create a scripting language. By reading the JavaScript documentation, you learn how to use a scripting language.
When people call JavaScript a “dialect of the ECMAScript language,” they mean it in the same sense as when talking about English, French, or Chinese dialects. A dialect derives most of its lexicon and syntax from its parent language, but deviates enough to deserve distinction.
A JavaScript engine
A program or interpreter that understands and executes JavaScript code.
Synonyms: JavaScript interpreter, JavaScript implementation
JavaScript engines are commonly found in web browsers, including V8 in Chrome, SpiderMonkey in Firefox, and Chakra in Edge. Each engine is like a language module for its application, allowing it to support a certain subset of the JavaScript language.
A JavaScript engine to a browser is like language comprehension to a person. If we re-visit our example of the actions “walk”, “run”, “jump”, a JavaScript engine is the part of an “entity” that actually understands what these actions mean.
This can explain the fact that different browsers have different performances and support different features of javascript.
If you will recall, ECMAScript is a specification for what a scripting language could look like. Releasing a new edition of ECMAScript does not mean that all JavaScript engines in existence suddenly have those new features. It is up to the groups or organizations who are responsible for JavaScript engines to be up-to-date about the latest ECMAScript specification, and to adopt its changes.
Transpilers
Programs that “translate” other programs from one language to another, or from one version of a language to another version of the same language.
When developers want to use the shiny new features that come with a new version of ECMASript, but may be concerned with cross-browser compatibility for their web apps, they can use compilers such as Babel to convert their code to a code with a previous and more widely supported version of ECMASript.
ECMAScript versions
New versions of ECMAScript are released every once in a while with new features that are progressively incorporated to browsers.
The ECMAScript standard is not a written in stone thing, but a standard that evolves in time together with the language and the browsers support.
One of the biggest evolutions of the standard was in it’s sixth version, released in 2015. The main features added in this version are:
- Arrow functions:
There are two benefits to arrow functions.
First, they are less verbose than traditional function expressions:
const
arr
=
[1,
2,
3];
const
squares
=
arr.map(x
=>
x
*
x);
// Traditional function expression:
const
squares
=
arr.map(function
(x)
{
return
x
*
x
});
Second, their
this
is picked up from surroundings (lexical). Therefore, you don’t needbind()
orthat = this
, anymore.
function
UiComponent()
{
const
button
=
document.getElementById('myButton');
button.addEventListener('click',
()
=>
{
console.log('CLICK');
this.handleClick();
// lexical `this`
});
}
- Modules:
JavaScript has had modules for a long time. However, they were implemented via libraries, not built into the language. ES6 is the first time that JavaScript has built-in modules.
ES6 modules are stored in files. There is exactly one module per file and one file per module. You have two ways of exporting things from a module. These two ways can be mixed, but it is usually better to use them separately.
Multiple named exports
There can be multiple named exports:
//------ lib.js ------
export
const
sqrt
=
Math.sqrt;
export
function
square(x)
{
return
x
*
x;
}
export
function
diag(x,
y)
{
return
sqrt(square(x)
+
square(y));
}
//------ main.js ------
import
{
square,
diag
}
from
'lib';
console.log(square(11));
// 121
console.log(diag(4,
3));
// 5
You can also import the complete module:
//------ main.js ------
import
*
as
lib
from
'lib';
console.log(lib.square(11));
// 121
console.log(lib.diag(4,
3));
// 5
Single default export
There can be a single default export. For example, a function:
//------ myFunc.js ------
export
default
function
()
{
···
}
// no semicolon!
//------ main1.js ------
import
myFunc
from
'myFunc';
myFunc();
Or a class:
//------ MyClass.js ------
export
default
class
{
···
}
// no semicolon!
//------ main2.js ------
import
MyClass
from
'MyClass';
const
inst
=
new
MyClass();
Note that there is no semicolon at the end if you default-export a function or a class (which are anonymous declarations).
Template literals:
Template literals are string literals that can stretch across multiple lines and include interpolated expressions (inserted via
${···}
):
const
firstName
=
'Jane';
console.log(`Hello ${firstName}!
How are you
today?`);
// Output:
// Hello Jane!
// How are you
// today?
Let and Const:
ES6 provides two new ways of declaring variables:
let
andconst
, which mostly replace the ES5 way of declaring variables,var
.
let
works similarly tovar
, but the variable it declares is block-scoped, it only exists within the current block.var
is function-scoped.In the following code, you can see that the
let
-declared variabletmp
only exists inside the block that starts in line A:
function
order(x,
y)
{
if
(x
>
y)
{
// (A)
let
tmp
=
x;
x
=
y;
y
=
tmp;
}
console.log(tmp===x);
// ReferenceError: tmp is not defined
return
[x,
y];
}
const
works likelet
, but the variable you declare must be immediately initialized, with a value that can’t be changed afterwards.
const
foo;
// SyntaxError: missing = in const declaration
const
bar
=
123;
bar
=
456;
// TypeError: `bar` is read-only
Destructuring:
Destructuring objects:
const
obj
=
{
first:
'Jane',
last:
'Doe'
};
const
{first:
f,
last:
l}
=
obj;
// f = 'Jane'; l = 'Doe'
Array destructuring
const
iterable
=
['a',
'b'];
const
[x,
y]
=
iterable;
// x = 'a'; y = 'b'
Promises:
Promises are an alternative to callbacks for delivering the results of an asynchronous computation. The Promise API is about delivering results asynchronously. A Promise object (short: Promise) is a stand-in for the result, which is delivered via that object.
A Promise is always in one of three mutually exclusive states:
- Before the result is ready, the Promise is pending.
- If a result is available, the Promise is fulfilled.
- If an error happened, the Promise is rejected.