Please note that these docs only cover a small subset of things that I was interesting in covering.
Standardised way to organise and reuse JavaScript code across different files using import and export statements for better modularity and maintainability.
Before ES6:
ES6 introduced:
For static fields:
class Example { static maxAge = 150; } Example.maxAge // 150
Initialization block:
class Example { #maxAge = 150 static { console.log("I'm in the static init block") } getMaxAge() { return this.#maxAge } } Example.maxAge // 150
It's "like a constructor for static values".
When the class code loads, the static initialisation block is invoked.
This is not actually a syntax change, it's an improvement for improving recursion. It changes how recursive performance works when recusing using a call to itself.
function factorial(n, acc = 1) { if (n === 0) { return acc; } else { return factorial(n - 1, n * acc) } }
See more here https://webkit.org/blog/6240/ecmascript-6-proper-tail-calls-in-webkit/
Enables us to do something by being a proxy prior to a change using traps.
The example code given:
const target = { name: "Joseph" } const handler = { get: (obj, prop) => { console.log(`Trying to get ${prop} from ${JSON.stringify(obj)}`) return Reflect.get(obj, prop) || 'default' } } const proxy = new Proxy(target, handler) console.log(proxy.name)
Read more on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#description
const sym = new Symbol('description') const obj = { [sym]: 'value' } console.log(obj[sym]) const globalSymbol = new Symbol('description')
Two different symbols are not identical to each other.
Read more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for
Some more code examples:
console.log(Symbol.for('bar') === Symbol.for('bar')); // Expected output: true console.log(Symbol('bar') === Symbol('bar')); // Expected output: false const symbol1 = Symbol.for('foo'); console.log(symbol1.toString()); // Expected output: "Symbol(foo)" const symbolA = Symbol("A") class A { _tag = symbolA _generic = "A" getTag() { return this._tag } getGeneric() { return this._generic } } const symbolAltA = Symbol("A") class AltA { _tag = symbolAltA _generic = "A" getTag() { return this._tag } getGeneric() { return this._generic } } const a = new A() const ab = new A() const altA = new AltA() console.log(a.getTag() === ab.getTag()) // true console.log(a.getTag() === altA.getTag()) // false console.log(a.getGeneric() === ab.getGeneric()) // true console.log(a.getGeneric() === altA.getGeneric()) // true
This is actually used a lot in the EffectTS codebase https://github.com/Effect-TS/effect/blob/main/packages/effect/src/Effect.ts
cause
is a new value that can be added to an error in ES2022.
throw new Error('Something went wrong', { // This was introduced in ES2022 for more metadata cause: new Error('Original error') })
Hash bang syntax is just #!/usr/bin/env node
.
We can create a weak reference with the WeakRef
constructor.
The idea is that weak references do not care if they lose the reference if nothing else is used.
Some useful situations may be have cyclic references, or passing values down into other libraries etc.
To access an object through a week reference, you need to use <var-name>.deref().<property>
.
You probably won't use this too often unless using things like WebGL or WASM.
The FinalizationRegistry
is like a hook that runs when an object is being released in memory by a garbage collector.
Just some notes that there were some improvements made to things like supporting unicode flags to name positions, etc.
Worth knowing for future reference.