TC39 proposal author has been concerned about, save some interesting today to chat.

PS: There are five phases of the proposal, and only phase 4 will be included in the release specification. The rest will only be included by chance.

.at()

This is a nice new syntax. Some other languages can use arr[-1] to fetch the elements at the end of an array, but this is impossible for JS. Because [key] is the object fetching the value of the key. Arrays are also objects, and using arr[-1] for arrays is to get a value with key -1.

Arr [arr.length-1] : arr[arr.length-1] : arr[arr.length-1] : arr[arr.length-1] : arr[arr.length-1] : arr[arr.length-1] : arr[arr.length-1]

// Polyfill
function at(n) {
    // ToInteger() abstract op
    n = Math.trunc(n) || 0;
    // Allow negative indexing from the end
    if(n < 0) n += this.length;
    // OOB access is guaranteed to return undefined
    if(n < 0 || n >= this.length) return undefined;
    // Otherwise, this is just normal property access
    return this[n];
}
Copy the code

The top await

As I’m sure you all know, this limitation prevents us from using ‘await’ directly in our global scope. We have to wrap ‘await’.

With this proposal, people can write “await” directly at the top level, which is a convenient proposal.

The proposal is now in phase 4 and is set to be released. In fact, a recent update to Chrome already supports this feature.

Error Cause

This syntax mainly helps us pass errors easily. Once there’s a lot that can go wrong, it’s not really clear where the mistake came from. If we want context information to be clear to the outside world, we need to encapsulate the following error.

async function getSolution() {
  const rawResource = await fetch('//domain/resource-a')
    .catch(err= > {
      // How to wrap the error properly?
      // 1. throw new Error('Download raw resource failed: ' + err.message);
      // 2. const wrapErr = new Error('Download raw resource failed');
      // wrapErr.cause = err;
      // throw wrapErr;
      // 3. class CustomError extends Error {
      // constructor(msg, cause) {
      // super(msg);
      // this.cause = cause;
      / /}
      / /}
      // throw new CustomError('Download raw resource failed', err);
    })
  const jobResult = doComputationalHeavyJob(rawResource);
  await fetch('//domain/upload', { method: 'POST'.body: jobResult });
}

await doJob(); // => TypeError: Failed to fetch
Copy the code

So with this syntax, we can simplify our code like this:

async function doJob() {
  const rawResource = await fetch('//domain/resource-a')
    .catch(err= > {
      throw new Error('Download raw resource failed', { cause: err });
    });
  const jobResult = doComputationalHeavyJob(rawResource);
  await fetch('//domain/upload', { method: 'POST'.body: jobResult })
    .catch(err= > {
      throw new Error('Upload job result failed', { cause: err });
    });
}

try {
  await doJob();
} catch (e) {
  console.log(e);
  console.log('Caused by', e.cause);
}
// Error: Upload job result failed
// Caused by TypeError: Failed to fetch
Copy the code

Pipe operator

This syntax has a large number of stars, more than 5K, and the side shows that it is a popular syntax. However, it should be a long time before it is released. After all, this proposal was made three or four years ago, and it is only phase 1 at present.

This syntax is common in other functional programming languages, mostly for the convenience of function calls:

let result = exclaim(capitalize(doubleSay("hello")));
result //=> "Hello, hello!"

let result = "hello"
  |> doubleSay
  |> capitalize
  |> exclaim;

result //=> "Hello, hello!"
Copy the code

This is only for the use of a single parameter, but for those who are interested in other uses the proposal is open to reading, and there is a lot of content involved, which is probably the reason for the slow progress.

New data structure: Records & Tuples

This data structure will be particularly useful after the release of the author, there are two new data structures, we can declare by # :

  1. #{ x: 1, y: 2 }
  2. # [1, 2, 3, 4]

This data structure is immutable, similar to immer or immutable. Js introduced in React for performance optimization, where values accept only primitive or immutable data types.

const proposal = #{
  id: 1234.title: "Record & Tuple proposal".contents: `... `.// tuples are primitive types so you can put them in records:
  keywords: # ["ecma"."tc39"."proposal"."record"."tuple"]};// Accessing keys like you would with objects!
console.log(proposal.title); // Record & Tuple proposal
console.log(proposal.keywords[1]); // tc39

// Spread like objects!
constproposal2 = #{ ... proposal,title: "Stage 2: Record & Tuple"};console.log(proposal2.title); // Stage 2: Record & Tuple
console.log(proposal2.keywords[1]); // tc39

// Object functions work on Records:
console.log(Object.keys(proposal)); // ["contents", "id", "keywords", "title"]
Copy the code

The last

The above author listed a part of the interesting TC39 proposals, in addition to the above there are many proposals, if you are interested in TC39 readers can look for.