Stage | Purpose | Criteria | Implementation | |
---|---|---|---|---|
0 | Strawman | Allow input | None | N/A |
1 | Proposal | Describe the what, why and how |
|
Polyfills / demos |
2 | Draft | Precise syntax and semantics |
|
Experimental |
3 | Candidate | Gather feedback from implementations and users |
|
Spec compliant |
4 | Finished | Ready for inclusion to ECMA-262 |
|
Shipping |
// Rest
const obj = { foo: 1, bar: 2, baz: 3 };
const { foo, ...rest } = obj;
// foo is 1
// rest is { bar: 2, baz: 3 }
// Spread
const obj = { foo: 1, bar: 2, baz: 3 };
const other = { ...obj, qux: 4 };
// other is { foo: 1, bar: 2, baz: 3, qux: 4 }
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
const fsPath = "/root/path/to/the/Resource";
const regexp = /\/
(?<hierarchy>[^\/]+)
(?<membership>\/.*?)[\/]*
(?<name>[^\/]*)
$/u;
const { groups } = regexp.exec(fsPath)
// {
// hierarchy: "root",
// membership: "/path/to/the",
// name: "Resource",
// }
catch
binding
let isTheFeatureImplemented = false;
try {
// Check if it is
isTheFeatureImplemented = true;
} catch { }
const main = document.querySelector("main");
const dynamicModule = "myfile";
import(`./dynamic/${ dynamicModule }.js`)
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
globalThis
window
, this
, self
global
or this
global
class Counter {
// Public, private and static fields
publicValue = 0;
#privateValue = 0;
static staticField = 0;
// Private getters and setter
get #value() { return #privateValue; }
set #value(val) {
this.#privateValue = val;
}
constructor() {}
// Private methods
#increment() {
this.#privateValue++;
}
}
BigInt
: Arbitrary precision integers
JS only supports integers up to 253-1
// Literal + constructor
const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
const hugeButString = BigInt('9007199254740991');
// ↪ 9007199254740991n
// Same operators as with Number
const bigN = 2n ** 54n;
// ↪ 18014398509481984n
// Array.prototype.flat( [ depth ] )
const nestedArr = [[1], [2, 3], [4]]
nestedArr.flat()
// > [1, 2, 3, 4]
// Array.prototype.flatMap( mapperFunction [ , thisArg ] )
const nestedArr = [[1], [2, 3], [4]]
nestedArr.flatMap(x => x + 1)
// > [2, 3, 4, 5]
Object.entries
obj = Object.fromEntries([
['a', 0],
['b', 1]
]);
// obj is { a: 0, b: 1 }
@defineElement("num-counter")
class Counter extends HTMLElement {
@observed #x = 0;
@bound
#clicked() {
this.#x++;
}
@bound
render() {
this.textContent = this.#x.toString();
}
}
A modern immutable date time API
Object Name | Description | Example |
---|---|---|
CivilDate |
Date | 2017-12-31 |
CivilTime |
Time of day | 17:00:00 |
CivilDateTime |
Date and time | 2017-12-31T12:00:00 |
Instant |
Point in timeline w/o time zone | 2017-12-31T00:00:00Z |
ZonedInstant |
Point in timeline with time zone | 2017‑12‑31T09:00:00+09:00[Asia/Tokyo] |
Proposal | Stage 1 | Stage 2 | Stage 3 | Stage 4 | Time (months) |
---|---|---|---|---|---|
Object Rest spread | 2014-09 | 2015-07 | 2016-09 | 2018-01 | 40 |
Async iterators | 2016-01 | 2016-03 | 2016-09 | 2018-01 | 24 |
RegEx Unicode escape | 2016-07 | 2016-09 | 2017-03 | 2018-01 | 18 |
Promise.finally | 2016-07 | 2016-07 | 2017-07 | 2018-01 | 18 |
JSON superset | 2017-09 | 2017-11 | 2018-01 | 2018-05 | 8 |
Private methods & accessor | ??? | 2017-07 | 2017-09 | ||
Public Class fields | ??? | 2016-07 | 2017-07 | ||
String.prototype.matchAll | 2015-09 | 2017-09 | 2018-01 | ||
String.prototype.{trimLeft,trimgRight} | 2015-07 | 2016-07 | 2018-01 | ||
System.global | ??? | 2016-03 | 2016-09 | ||
dynamic import() | 2016-09 | 2016-09 | 2016-12 | ||
Temporal | 2017-03 | 2018-09 | |||
String.prototype.replaceAll | 2017-11 | ||||
do expression | 2017-01 |
Babel and TypeScript allow new features even before full browser support
Enables faster feedback loop between web developers and implementors
Lots of interesting proposals
JS is becoming ever more multi-paradigm
Transpilers allow early usage of features