URL objects have both a search property that shows the query parameters as a single string and searchParams, a URLSearchParams object with which you can manage the params without having to think about URL encoding or any nastiness.

const myUrl = new URL("https://example.com/my-page?id=1&q=search%20term");

myUrl.search === "?id=1&q=search%20term"
myUrl.searchParams.get("q") === "search term"
myUrl.searchParams.set("q", "other search term");

// {id: '1', q: 'other search term'}
Object.fromEntries(myUrl.searchParams.entries());
Read more

There's a relatively new (but safe to use, because you don't care about IE anymore) native JS method to deep-copy (also referred to as "cloning") objects: structuredClone().

For example:

myObject = {a: 1, b: {c: 2}};
myDeepCopy = structuredClone(myObject);
Read more

In async functions in JavaScript, returning the result from an async function (i.e. a Promise object) is the same as returning the fulfilled value from that Promise. In code, assuming innerFn is async, this:

async function outerFn() {
  return await innerFn();
}

is the same as this:

async function outerFn() {
  return innerFn();
}
Read more

As with most things in JavaScript, there's a workaround to access the elements on a "closed" shadow DOM: hijacking the attachShadow method:

Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    return this._attachShadow( { mode: "open" } );
};
Read more

The 2-digit option in the Intl.DateTimeFormat API doesn't always do what you might expect. In particular, this piece of code doesn't produce a 2-digit number:

const dt = Date.parse('2000-01-02T03:04:05');

new Intl.DateTimeFormat('en-US', {minute: '2-digit'}).format(dt) === "4" // doesn't this look like it should be "04"?

However, it turns out this is not strictly a bug.

Read more

setTimeout usually takes a function and a delay argument, but it can also accept more arguments that are passed to the given function. This can make code easier to read, at the cost of having yet another way of doing the same thing.

Read more

You can import ES6-style JavaScript modules dynamically using await import(filename);. For example:

const {default: renamedDefaultExport, namedExport1, namedExport2} = await import("./mymodule.js");
Read more

You can send a request when a page is closed, either using the Fetch API with the keepalive option:

const url = "http://example.com/my/resource";
const data = {a: 1, b: 2}; // some data to be logged, such as usage statistics
const handler = () => fetch(url, {method: "POST", keepalive: true});
window.addEventListener("unload", handler);

Or the Beacon API:

const blob = new Blob([JSON.stringify(data)], {type: "application/json"});
const handler = () => navigator.sendBeacon(url, blob);
Read more

There is no JavaScript event for a URL change. There is one, however, for when the fragment changes (the part after the # symbol), called hashchange, and there is another, popstate, which doesn't always get triggered, for when the user clicks on the back or forward buttons or the history.back() or history.go() methods are called.

Read more
Subscribe to JavaScript
Mastodon Mastodon