JavaScript Temporal API — A Fix for the Date API

Anyone who has worked with dates and time in JavaScript knows how broken the built-in Date is. In the near future we’ll be able to use Temporal instead, an ECMAScript feature currently at Stage-3

💁‍♂️ Stage-3?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-3 is the Candidate Stage where the feature is considered complete and only critical changes will happen based on implementation experience. If all goes well the proposal will advance to Stage 4 without any changes, after which it will to become part of the ECMAScript Specification.

Nathan Sebhastian has a good overview on how it compares to Date, along with some practical examples.

The new Temporal API proposal is designed to solve the problems with the Date API. It brings the following fixes to JavaScript date/time manipulation:

  • Creating and dealing only with immutable Temporal objects
  • Straightforward API for date and time computations
  • Support for all timezones
  • Strict date parsing from ISO-8601 format
  • Support for non-Gregorian calendars

JavaScript Temporal API — A Fix for the Date API →

What’s new in ES2021

With the January meeting of TC39 behind us, the Stage-4 features that will make it into ES2021 have been selected.

💁‍♂️ Stage-4?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-4 is the Finished Stage and indicates that the proposal is ready to become part of the ECMAScript Specification.

The following features will be part of ES2021, which will be formalised mid-2021:

Apart from the linked-to posts above, Pawel Grzybek has done a writeup on all features. Additionally you can check all posts tagged es2021 on the V8 blog.

☝️ Note that you can use (most of) these features today already, as browsers start rolling them out (unflagged) when they hit Stage-3. So no, you don’t have to wait until mid-2021 to start using them.

ESNext: Declarations in Conditionals (Stage-1)

An ECMAScript Language Feature that I’m looking forward to is Declarations in Conditionals. It adds the capability to declare variables inside conditional statements. Let’s take a look …

~

Setting the Scene

Say you want to iterate over an array which might be tucked away inside an object. To do so, you’d most likely first check for that variable’s existence using a simple if

if (user.meta.interests) {
    for (let interest of user.meta.interests) {
        // …
    }
}

As we’re now typing user.meta.interests twice in our code you might declare an intermediary variable, and use that further down in your code:

let interests = user.meta.interests;
if (interests) {
    for (let interest of interests) {
        // …
    }
}

But now you have a nasty side-effect: you’re loitering the scope with this extra interests variable. This is quite useless, as you’re only using it inside the if statement.

💁‍♂️ To make it totally failsafe, you might also want to add some Optional Chaining in there and check if interests is iterable, but that’s beyond the scope of this post.

~

Hello “Declarations in Conditionals”

With the “Declarations in Conditionals” proposal we can keep this extra interests variable, yet without loitering the outer scope. We do this by declaring the variable directly inside the conditional (e.g. if statement), like so:

if (let interests = user.meta.interests) {
    for (let interest of interests) {
        // …
    }
}

⚠️ Note that this is an assignment right there, not an equality check!

With that one line the interests variable:

  1. will be declared
  2. will have a value assigned to it
  3. will be checked for being falsy or not

Scope-wise the interests variable will have its scope limited local to the conditional (e.g. only visible inside the if).

The proposal limits declarations to use either const or let; declarations in conditionals with var are currently not allowed.

💡 You might not 100% realize it, but you’re already doing this kind of thing when using a for loop. Inside its initialization part (e.g. its first part) you are also declaring variables.

for (let i = 0; i < 5; i++) {
  console.log(i);
}

☝️ Did you know that you can declare more than one variable there, separated by a comma? In the example below I declare an extra variable len right after declaring i:

const cars = ['Ford', 'Mercedes', 'BMW'];

for (let i = 0, len = cars.length; i < len; i++) {
  console.log(cars[i]);
}

🤔 What about the scope of len you might ask? Variables declared using let are scoped to the statement (e.g. local to the loop). Variables declared using var get hoisted. And oh, it’s not allowed to declare variables using const here.

~

So, when can we use this?

The proposal is currently Stage-1, so it still has a long way to go before it can become an official part of the standard — if it ever will be.

💁‍♂️ Stage-1?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-1 is the Proposal stage. It signals that the committee is showing interest in the proposal and that it is seeking further investigation on how to tackle it. At this stage the proposal is subject to heavy changes. It is only when a proposal reaches Stage 4 that it is ready to become part of the ECMAScript Specification.

As it’s still Stage-1, it can change quite a lot before it to be finished. And I’m quite sure it will change, as right now:

  • It only allows declaring one variable.
  • It only checks for values being falsy or not.

These two feature are currently listed under “Future Work” of the proposal, and it looks like this:

if (let x = 1, y = 2; x || y) {
    // …
}

Must say I’m pretty curious how this one will evolve, as I’m already quite excited about it: it’s one of those small additions that will have a pretty big impact on how I write my code.

If you have an addition to this proposal, feel free to join the discussion in the Declarations in Conditionals GitHub repository.

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

ESNext: Proposals to look forward to (ESNEXT Conf)

Happening right now is ESNEXT Conf a fully remote conference exploring the future of JavaScript and the web. When I saw the CFP float by, it sounded like a perfect match for my talk “ESNext: Proposals to look forward to”. Thankfully the organisers – Fred and Drew from Pika – also felt that ways and the put me in the line-up.

With the yearly ECMAScript releases (ES2015..ES2020) of a lot of things have changed in JavaScript-land, and there’s even more to come. This talk takes a look at a few of the newest (ES2020) and some of the upcoming ECMAScript features, which (hopefully) will become part of the ECMAScript Language Specification in the near future.

~

Talk Slides

The slides are up on slidr.io, and also embedded below:

~

Talk Outline

  • ECMAScript History and Timeline
  • TC39: Info on TC39, what they do, and how they work.
  • ESNext Proposal: Field Declarations
  • ES2020 Feature: Optional Chaining
  • ES2020 Feature: Null Coalescing
  • ESNext Proposal: Logical Assignment
  • ES2020 Feature: Dynamic Imports
  • ESNext Proposal: Decimal
  • ESNext Proposal: Cancellation API (+ Mention of AbortController)
  • ESNext Proposal: Declarations In Conditionals
  • ES2019 Feature: Object.fromEntries()
  • ESNext Proposal: Slice Notation
  • ESNext Proposal: Pattern Matching
  • Fin.

~

Talk Video

Once the video has been released, I’ll update this post to include it. Here it is:

~

Thanks to the organisers for having me, and thanks to the attendees for coming to see me. I hope you all had fun attending this talk. I know I had making it (and whilst bringing it forward). A shame we couldn’t meet in person though, perhaps at a next edition 😉

💁‍♂️ If you are a conference or meetup organiser, don’t hesitate to contact me to come speak at your event.

ESNext: Proposals to look forward to (JS VidCon / JavaScript Remote Conf)

The past few days I’ve been attending some virtual conferences. At JS VidCon and JavaScript Remote Conf I also joined as a speaker, to bring forward my ever-evolving talk “ESNext: Proposals to look forward to”

With the yearly ECMAScript releases (ES2015..ES2020) of a lot of things have changed in JavaScript-land, and there’s even more to come. This talk takes a look at a few of the newest (ES2020) and some of the upcoming ECMAScript features, which (hopefully) will become part of the ECMAScript Language Specification in the near future.

The slides are up on slidr.io, and also embedded below:

Talk Outline:

  • JavaScript Yellow: How to get JavaScript Yellow on your website (a plea to using the right tool for the right job)
  • TC39: Info on TC39, what they do, and how they work.
  • ESNext Proposal: Field Declarations
  • ESNext Proposal: Pipeline Operator
  • ES2020 Feature: Optional Chaining
  • ES2020 Feature: Null Coalescing
  • ESNext Proposal: Logical Assignment
  • ES2020 Feature: Dynamic Imports
  • ESNext Proposal: Export Default From
  • ESNext Proposal: Decimal
  • ESNext Proposal: Cancellation API (+ Mention of AbortController)
  • ESNext Proposal: Declarations In Conditionals
  • ESNext Proposal: Slice Notation
  • ES2019 Feature: Object.fromEntries()
  • ESNext Proposal: Pattern Matching
  • Fin.

Thanks to the organisers for having me, and thanks to the attendees for coming to see me. I hope you all had fun attending this talk. I know I had making it (and whilst bringing it forward). A shame we couldn’t meet in person though, perhaps at a next edition 😉

💁‍♂️ If you are a conference or meetup organiser, don’t hesitate to contact me to come speak at your event.

ESNext: Logical Assignment Operators (||=, ??=, &&=)

Update 2020.07.21:

This proposal made it into Stage-4 and will officially be part of ES2021 🥳

💁‍♂️ Stage-4?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-4 is the Finished Stage and indicates that the proposal is ready to become part of the ECMAScript Specification.

A new ECMAScript Proposal that I’m looking forward to is Logical Assignment Operators. In short it combines Logical Operators (||, &&, and ??) with Assignment Expressions (=).

// "Or Or Equals" (or, the Mallet operator)
a ||= b;

// "And And Equals"
a &&= b;

// "QQ Equals"
a ??= b;

Basically these operators translate to these actions being performed:

  • ||= will only assign the value of b into a if a is falsy (false, 0, null, etc.).
  • &&= will only assign the value of b into a if a is truthy (true, 1, {}, etc.).
  • ??= will only assign the value of b into a if a is null or undefined.

🤔 Not familiar with that ?? you see there? It’s the Nullish Coalescing Operator which is part of ES2020 and it’s awesome!

~

These operators will change the way you code, see this before/after example:

// Without Logical Assignment
name = name ?? 'stranger';

// With Logical Assignment
name ??= 'stranger'

Using Logical Assignment Operators will save you to writing an if statement. Additionally it can save a setter execution.

let name = 'bramus';

// Without Logical Assignment: the value of name will *always* be set to (here: to its own value), even though name is not nullish
name = name ?? 'stranger';

// With Logical Assignment: name won't be reassigned as name is not nullish
name ??= 'stranger'

~

The Logical Assignment Operators proposal is currently Stage-3.

💁‍♂️ Stage-3?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-3 is the Candidate Stage where the feature is considered complete and only critical changes will happen based on implementation experience. If all goes well the proposal will advance to Stage 4 without any changes, after which it will to become part of the ECMAScript Specification.

Since it’s Stage-3, we can expect things to look good implementation-wise, which it totally is:

  • Babel: The “Mallet Operator Transformer” got added a long time ago (back when it was still called “6to5”). Nowadays you should use the @babel/plugin-proposal-logical-assignment-operators plugin.
  • Chrome/V8: The feature got added two days ago and will get shipped with V8 v8.4 behind the flag --harmony-logical-assignment
  • Firefox/SpiderMonkey: Version 77 should support it, but I couldn’t get it to work in Firefox Developer Edition (77.0b2). Firefox Nightly (78.0a1) works fine.
  • Safari/JavaScriptCore: Logical Assignment Operators shipped with Safari Technology Preview 105

I don’t expect this proposal to change at all anymore and can see it advancing to Stage-4 at the one of the next TC39 meetings. That way this proposal will most likely become part of ES2021.

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Worth It: Modern JS edition

“Worth It: Modern JS edition” is a small tool to analyze how much less JavaScript is downloaded in modern browsers as a result of it using the module/nomodule pattern.

Worth It: Modern JS edition →

💡 The module/nomodule pattern is a technique to ship ES2015 modules to browsers that support, whilst also keeping older browsers (that don’t support it) happy. It was covered here on bram.us back in July 2017

ESNext: Get localized language, currency, and region names with Intl.DisplayNames

An ECMAScript Internationalization API Feature that currently is in Stage-3 and that has already landed in V8 version 8.1 is Intl.DisplayNames. It’s a way to get localized display names for languages, scripts, regions and others.

🤔 Note that this proposal is part of ECMA-402 (the ECMAScript Internationalization API Specification) and not ECMA-262 (The ECMAScript Language Specification). Therefore this proposal will not be part of the yearly "ES20XX”, as that term only applies to ECMA-262.

To advance proposals in ECMA-402, TC39 uses the same 5-stage-process as they use in ECMA-262.

💁‍♂️ Stage-3?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-3 is the Candidate Stage where the feature is considered complete and only critical changes will happen based on implementation experience. If all goes well the proposal will advance to Stage 4 without any changes, after which it will to become part of the ECMAScript Specification.

The idea is that you as a developer should not build your own list of localized strings for languages, regions, etc. but that the JavaScript runtime should provide if for you:

Translation of languages, regions or script display names requires large amount of data to transmit on the network, which is already available in most browsers. The Intl.DisplayNames API will allow web developers to shrink the size of their HTML and/or ECMA script code without the need to include the human readable form of display names and therefore reduce the download size to decrease latency.

💁‍♂️ Another nice API exposed on Intl is Intl.RelativeTimeFormat which allows you to relatively format time in JavaScript.

~

Examples

// Get display names of region in English
const regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
console.log(regionNames.of('419')); // "Latin America"
console.log(regionNames.of('BZ')); // "Belize"
console.log(regionNames.of('US')); // "United States"
console.log(regionNames.of('BA')); // "Bosnia & Herzegovina"
console.log(regionNames.of('MM')); // "Myanmar (Burma)"

// Get display names of language in Traditional Chinese
const languageNames = new Intl.DisplayNames(['zh-Hant'], {type: 'language'});
console.log(languageNames.of('fr')); // "法文"
console.log(languageNames.of('zh')); // "中文"
console.log(languageNames.of('de')); // "德文"

// Get display names of script in Traditional Chinese
const scriptNames = new Intl.DisplayNames(['zh-Hant'], {type: 'script'});
console.log(scriptNames.of('Latn')); // "拉丁文"
console.log(scriptNames.of('Arab')); // "阿拉伯文"
console.log(scriptNames.of('Kana')); // "片假名"

// Get display names of currency code in English
const currencyNames = new Intl.DisplayNames(['en'], {type: 'currency'});
console.log(currencyNames.of('USD')); // "US Dollar"
console.log(currencyNames.of('EUR')); // "Euro"
console.log(currencyNames.of('TWD')); // "New Taiwan Dollar"
console.log(currencyNames.of('CNY')); // "Chinese Yuan"

~

Syntax

The constructor takes two arguments: locales and options. Both are optional:

new Intl.DisplayNames([locales[, options]]);

Once you have a Intl.DisplayNames instance, you use its .of method to request a localised string

Intl.DisplayNames.prototype.of(code);

~

Constructor Arguments

locales

The locales argument is a BCP 47 language tag which identifies the locale to use. The main parts, amongst others, of a BCP 47 language tag are language, script, and region

  • The language part is a 2/3 character long ISO 639-1 code
  • The (optional) script part is a 4 character long ISO 15924 code
  • The (optional) region part is a 2 alpha or 3 digit long ISO 3166-1 code

When more than one part is present, they are separated by a dash (-)

Examples:

  • "nl": Dutch (language).
  • "nl-BE": Dutch as used in Belgium (language + region).
  • "zh-Hans-CN": Chinese written in simplified characters as used in China (language + script + region).

When locales is omitted, it will default to the language-setting of the browser/system.

options

The options object allows you to tweak how Intl.DisplayNames behaves. It has the following properties:

  • localeMatcher

    The locale matching algorithm to use. Possible values are "lookup" and "best fit" (default)

  • style

    The length of the output message, e.g. "English (United States)" vs. "English (US)". Possible values are "long" (default) and "short", or “narrow” (which mostly yields the same result as "short", depending on the language)

  • type

    What you want to display. Possible values are "region", "script", "language", or "currency".

~

Intl.DisplayNames.prototype.of Arguments

code

Depending on the type you passed into the constructor, you pass in a different value for code:

~

JS/Browser Support

Intl.DisplayNames already shipped in V8 v8.1 (included in the upcoming Chrome 81) and will be available in Node 14. Other JS runtimes / browsers don’t support it at the time of writing.

~

The future: More types to come!

When looking at the open issues listed on the proposal’s repository you can see that there’s more to come in a future version of Intl.DisplayNames: support for units, timezones, emoji names, date parts (such as months, weekdays, etc).

For this first release the scope was limited to supporting the types "region", "script", "language", and "currency".

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

ES-Everything: an ECMA Explainer

Matthew Gerstman explaining a lot of terms that evolve around JavaScript: ECMA, TC39, Babel, Polyfills, …

So you Google how to make your app work in IE 10, or 11, or whatever. You’re quickly flooded with acronyms and terms you’ve never heard before ES5, ES6, ESNext, ES2020, TC39, ECMA. What’s a transpiler? People are debating about polyfills and ponyfills; is there a difference?

If you’re overwhelmed, that’s okay, it’s a lot. This article will attempt to cover the entire ecosystem around shipping new-ish JavaScript to older browsers and how the community decides what features get added to JavaScript in the first place; let’s dive in.

ES-Everything: an ECMA Explainer →