CookieStore API
Currently, browsers can store cookie/sessionStorage/localStorage/IndexedDB, all of which expose a very developer friendly API, except for cookies. Think back to how we normally manipulate cookies. For example, if you want to retrieve a cookie, you have to parse it manually to get the value of a cookie because document.cookie returns a string that is the union of all cookies.

If you want to add a cookie, then you need to convert the cookie to a string and assign it to document.cookie as below.

Isn’t it strange that document.cookie is a collection of all cookies, but adding a cookie is a direct assignment to document.cookie? Another oddity is that sometimes adding a cookie doesn’t work at all, but the browser doesn’t give any error messages, so you have to use getCookie after setCookie to see if it works.
However, deleting a cookie is even stranger, as we cannot just delete it, but let it expire.

A new CookieStore API has been introduced based on the above issues.
First, a cookieStore object is added to the window, and then get/set/delete methods are mounted on the cookieStore object for the get/add/delete operations of a single cookie. Note that get/set/delete all return a Promise, so exceptions need to be handled.
|
|
|
|
The cookieStore also provides the getAll method, which is used to obtain a list of cookies.
|
|
Previously, the only way to listen for cookie changes was to check for them at regular intervals using a timer, but cookieStore provides the ability to listen for cookie changes directly.
Compatibility and reference
Media Session API
If you want to control audio/video on a page, you can only do so by using the browser’s own control component or by implementing your own control component, and you will not be able to control audio/video when the page is unclickable (e.g. switching to another tab or minimizing the browser window).
The Media Session API exposes control of the page audio/video, enabling the system media centre to control the page audio/video, including basic information about the media being played (title/author/cover) and actions (play/pause/fast forward/fast rewind/next media/previous media).
|
|
The above example implements a basic MediaSession. The basic information is instantiated by the global object MediaMetadata, where artwork can be set to multiple values, and the browser automatically selects the best size for the scene, which is then assigned to navigator.mediaSession.metadata. Media control is set via the navigator.mediaSession.setActionHandler method, with play/pause/seekbackward/seekforward/previoustrack/nexttrack corresponding to play/pause/nexttrack respectively. play/pause/seekbackward/seekforward/previoustrack/nexttrack` operations. Once the media has been played, the browser maps the basic information and actions to the system and provides the corresponding action menus in the system.
Under Windows 10, for example, the Media Control Panel appears near the volume control.

On Android, the Media Control Panel will appear in the status bar.

The Media Control Panel also appears in the header of some browsers.

Compatibility and reference
Shape Detection API
QR codes are everywhere nowadays, but recognising them on the web is not an easy task, either by uploading them to the backend for parsing or by using complex JS libraries. The new BarcodeDetector feature provides a user-friendly API to recognize QR codes locally without the backend.
To use BarcodeDetector you first need to instantiate it, and then pass the image data to the detect method of the instance, which is an asynchronous operation, so the return value is a Promise. Also, a single image may contain multiple QR codes, so the result is an array.
|
|
BarcodeDetector not only recognises 2D codes, but also supports various barcode formats, including aztec / code_128 / code_39 / code_93 / codabar / data_matrix / ean_13 / ean_8 / itf / pdf417 / qr_code / upc_a / upc_e . BarcodeDetector recognises all barcode formats by default, if you only want to recognise certain formats, you can specify this when instantiating:
The BarcodeDetector is part of the Shape Detection API, in addition to the TextDetector and the FaceDetector, which correspond to text recognition and face recognition respectively, the following is an example of text recognition
TextDetectoris not yet stable, so it may not be able to recognize text on canvas, and uploaded images may not be recognized accurately.
|
|
Compatibility and reference
- Can I use
- Accelerated Shape Detection in Images
- The Shape Detection API: a picture is worth a thousand words, faces, and barcodes
Top-level await
Previously the await keyword was only allowed inside the async function, top-level await allows us to use the await keyword directly outside the async function.
Use the script above top-level await to directly remove the async function .
If a module uses top-level await , then other modules that refer to it will wait for it to resolve .
In the above code, the output order is 1 2 react, which means that the b module will wait for the a module to resolve before it continues to execute. Similarly, when the a module reject, the b module will not work properly. For the b module to work properly, an error handler needs to be added to the a module.
|
|
The top-level await is ideal for certain scenarios.
Conditional introduction of modules
We know that static import does not allow for conditional import, for example the following code is not legal.
Conditional static imports can be simulated by using top-level await in conjunction with dynamic import.
Dependency fallback
When we introduce a static module, if the module fails to load, then all other modules that reference it will not work properly.
Dependency fallback can be achieved with top-level await and dynamic import.
Resource initialization
Previously, when a resource needed to be initialized asynchronously, it was usually written in the following way.
Note that the above code is only an example, there is a lot of error handling required in practice
In the above code, the synchronous sendMessage method is forced to become asynchronous by the asynchronous getWs method, which can be avoided by using top-level await.
Compatibility and reference
BigInt
In JavaScript, the range of integers is [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER], which is from the 53rd power of minus 2 minus 1 to the 53rd power of 2 minus 1, outside of which precision is not guaranteed, for example:

If you want to accurately represent integers beyond SAFE_INTEGER, it is common to convert them to strings and then implement various string operations (I’m sure many of you have done the algorithm for adding strings of numbers, e.g. '123' + '789' = '912').
BigInt can represent an arbitrarily large integer, even if it is outside the range of SAFE_INTEGER, to ensure precision. A BigInt can be declared by adding n to the number or by using the BigInt method:
The above a / b / c all represent 123n . BigInt supports the + / - / * / / / ** / % operators, but cannot be mixed with other types:
|
|
BigInt can be converted to number, and if BigInt exceeds the range of SAFE_INTER, then the converted number will lose precision:
BigInt also supports comparison operations, and can be compared with number:
BigInt also has some limitations, firstly it does not support calling methods on Math objects, and secondly it does not support JSON.stringify, so if you want to serialize it, you can implement the toJSON method of BigInt:
Note that BigInt is a normal method like Symbol, not a constructor, so it cannot be instantiated by new:
|
|
JavaScript has 7 data types
undefined/null/boolean/number/string/symbol/object,BigIntis the 8th data type, the value oftypeof 1nisbigint, and is a basic type.
Compatibility and reference
Number separators
Often, if a number is unusually large, we add separators to the display to make it more readable:

is now usually a thousand-digit separator, supposedly derived from the English thousond/million/billion/trillion/…, with a proper noun for each additional 3 digits (https://en.wikipedia.org/wiki/Namesoflarge_numbers). For me it’s more of a ten-thousand separator, probably because I got used to it in primary school maths.
But at JavaScript level, we can only concatenate numbers no matter how big they are, e.g. 1032467823482.32134324, which requires careful counting to get the exact value.
Now, the Numeric separators feature allows the insertion of _ separators between numeric literals to make them more readable.
_ The separator can appear in the integer part, or in the decimal part. In addition to decimal, separators can also appear in other decimal systems
The above code adds separators every 3 digits, however, it is important to note that separators can only be added between numbers, not at the beginning/end of numbers/binary symbols/decimal points/scientific notation, and not two separators in a row, as the following separator positions are wrong.
The number separator is only there to improve readability and has no real meaning; numbers with a separator are converted to strings without the separator. Similarly, strings with _ are not converted to numbers correctly
In addition, the number separator also applies to the BigInt mentioned above.
Compatibility and references
New syntax for CSS colour methods
There are 4 colour methods in CSS, rgb / rgba / hsl / hsla . Previously, the arguments to each method were separated by a comma, but now the new syntax for rgb / hsl allows the comma to be omitted and the arguments to be separated by a space.
While omitting the comma, rgb / hsl both support the 4th parameter, indicating transparency, thereby replacing rgba and hsla .
Where, the spaces on either side of / are optional.
Compatibility and references
aspect-ratio
If you want to achieve a rectangle with a specified ratio, you usually use padding, which takes advantage of the fact that the percentage is calculated based on the width of the parent element, but the real content often needs to be placed in an additional child element and absolute positioning needs to be set:
|
|
The aspect-ratio property allows us to set the aspect ratio of an element directly. The example above using aspect-ratio would look like this
Compatibility and reference
gap
The grid-gap property can be used to set row-to-row and column-to-column gaps in the grid layout, but now the gap property can be used directly instead of grid-gap, and the gap property adds support for flex and column-count.
|
|
Compatibility and reference
CSS math functions
The calc method can be used to perform mathematical calculations in CSS, and now there are three new methods min / max / clamp .
The min method takes one or more values and returns the smallest of them, e.g. width: min(1vw, 4rem, 80px); , if the width of viewport is equal to 800px , then 1vw === 8px , 4rem === 64px , so the result is width: 1vw; .
The max method takes one or more values and returns the maximum of them, in the example above, the result is width: 80px; .
The clamp method takes 3 values clamp(MIN, VAL, MAX) , from left to right they are min/preferred/max values, if the preferred value is less than the min value then the min value is returned, if it is greater than the max value then the max value is returned, if the preferred value is between the min and max values then the preferred value is returned, the logic can be expressed in JS like this
That is, clamp limits the range of values of VAL, e.g. width: clamp(1rem, 10vw, 2rem); where the width of viewport is equal to 800px, the result is width: 2rem; , because (10vw = 80px) > (2rem = 32px) .
Interestingly, min / max / clamp can also be nested with other methods, such as clamp(1rem, calc(10vw - 5px), min(2rem, 20vw)) , so clamp can be written as max(MIN, min(VAL, MAX)) or min(MAX, max (VAL, MIN)) .