This article shows all of the features that ECMAScript versions offer, in reverse order and through code examples or a simple list. It is designed to provide you with a quick list of ECMAScript features as you code

ES2021-ES12

String.protype.replaceAll

Before ES2021, to replace all specified characters in a string, we can do this:

const str = "a+b+c+";
const newStr = str.replace(/\+/g."🤣");
console.log(newStr); / / a 🤣 🤣 🤣 c b
Copy the code

ES2021 takes the replaceAll method and mounts it on the String prototype. It can be used as follows:

const str = "a+b+c+";
const newStr = str.replaceAll("+"."🤣");
console.log(newStr); / / a 🤣 🤣 🤣 c b
Copy the code

Promise.any

Promise.any

  • Receive a Promise iterable and return the successful Promise if any Promise succeeds
  • If all promises fail/reject, return a failed promise

Promise.race

  • Whenever the state of any promise changes (whether it succeeds or fails), that promise is returned

Promise. All the contrast

  • If any promise fails, the failed promise is returned
  • When all asynchronous operations have been successful, the promise is returned as an array of values
const pErr = new Promise((resolve, reject) = > {
  reject("Always fail.");
});

const pSlow = new Promise((resolve, reject) = > {
  setTimeout(resolve, 500."Finished");
});

const pFast = new Promise((resolve, reject) = > {
  setTimeout(resolve, 100."Soon.");
});

// 使用 .then .catch
Promise.any([pErr, pSlow, pFast])
  .then((value) = > {
    // Return the first successful promise: pFast-" finish soon"
    console.log(value);
  })
  .catch((err) = > {
    // Triggers when all promises fail
  });

/ / use the async - await
try {
  const first = await Promise.any(promises); // Any promise is returned successfully.
  console.log(first);
} catch (error) {
  // All of his promises failed
  console.log(error);
}
Copy the code

WeakRef

WeakRef proposal mainly contains two new features:

  • Can be achieved byWeakRefClass to create a weak reference to an object
  • Can be achieved byFinalizationRegistryClass to perform custom methods after an object has been garbage collected

These two new features can be used together or separately, depending on your needs. A WeakRef object contains a weak reference to an object, called a target or reference. Weak references to an object allow it to be collected by the garbage collection mechanism without any other references. WeakRef is used to cache and map large objects. WeakRef is used when you want an object to be garbage collected in time without being referenced elsewhere.

function toogle(element) {
  const weakElement = new WeakRef(element);
  let intervalId = null;

  function toggle() {
    const el = weakElement.deref();
    if(! el) {return clearInterval(intervalId);
    }
    const decoration = weakElement.style.textDecoration;
    const style = decoration === "none" ? "underline" : "none";
    decoration = style;
  }
  intervalId = setInterval(toggle, 1000);
}
const element = document.getElementById("link");
toogle(element);
setTimeout(() = > element.remove(), 10000);
Copy the code

FinalizationRegistry receives a registry callback function that can be used to register an event listener for a specified object. When the object is garbage collected, the monitored event will be triggered, as follows. First, create a registry:

const registry = new FinalizationRegistry((heldValue) = > {
  / /...
});
Copy the code

We can then register a specified object, and we can also pass some parameters to the registry callback:

registry.register(theObject, "some value");
Copy the code

Logical assignment operator

See TS39-proposal-logical-assignment for more information

The logical assignment operator combines a logical operator and an assignment expression. There are two kinds of logical assignment operators:

  • Or equal to (| | =)
  • And is equal to (&& =)
  • ?? =

| | =

const giveKey = () = > {
  return "somekey";
};
let userDetails = { name: "chika".age: 5.room: 10.key: "" };
userDetails.key ||= giveKey();
console.log(userDetails.key);

//output : somekey
Copy the code

&& =

const deleteKey = () = > {
  return "";
};
let userDetails = { name: "chika".age: 5.room: 10.key: "990000" };
userDetails.key &&= deleteKey();
console.log(userDetails.key);

//output : ""
Copy the code

?? = Empty assignment operator

?? = is also known as the empty assignment operator, related to the non-airlift operator above. Look at the connection:

var x = null;
var y = 5;
console.log((x ?? = y));/ / = > 5
console.log((x = x ?? y)); / / = > 5
Copy the code

This assignment operator is assigned only if the value is null or undefined. The example above emphasizes that this operator is essentially a syntactic sugar for empty assignments (similar syntactic sugar: a = a + b can be written as a += b). Next, let’s look at the difference between this operator and the default argument (which is a new syntax introduced in ES6 that sets a default value only if the function argument is undefined) :

function gameSettingsWithNullish(options) { options.gameSpeed ?? =1; options.gameDiff ?? ="easy";
  return options;
}
function gameSettingsWithDefaultParams(gameSpeed = 1, gameDiff = "easy") {
  return { gameSpeed, gameDiff };
}
gameSettingsWithNullish({ gameSpeed: null.gameDiff: null }); // => {gameSpeed: 1, gameDiff: 'easy'}
gameSettingsWithDefaultParams(undefined.null); // => {gameSpeed: 1, gameDiff: null}
Copy the code

There is a notable difference in the way the above functions handle nulls. The default argument will override the default with an empty argument (null here, only undefined), and the empty assignment operator will not. Default arguments and empty assignments do not override undefined values. MDN official document

const getKey = () = > {
  return "somekey";
};
let userDetails = { name: "chika".age: 5.room: 10}; userDetails.key ?? = getKey();console.log(userDetails.key);

//output : "somekey"
Copy the code

Number separator

With this feature, we use the \_, U+005F separator to group numbers and improve the readability of numbers:

1 _000_000_000; / / one billion
101 _475_938. 38; / / one hundred million

const amount = 12345 _00; // 12,345
const amount = 123 _4500; // 123.45 (keep 4 decimal places)
const amount = 1 _234_500; / / 1234500

0.000 _001; // One part per million
1e10_000; / / 10 ^ 10000

//
const binary_literals = 0b1010_0001_1000_0101;
const hex_literals = 0xa0_b0_c0;
//
const bigInt_literals = 1_000_000_000_000n;
//
const octal_literal = 0o1234_5670;
Copy the code

ES2020-ES11

ES2020 is the equivalent version of ECMAScript for 2020

String.protype.matchAll

The matchAll() method returns all matches of a regular expression in the current string

However, it returns an Iterator, not an array. It is very simple to convert the iterator into an array, using… The operator and the array.from () method do the job.

const string = "test1test2test3";
const regex = /t(e)(st(\d?) )/g;

const newdata = string.matchAll(regex);

for (const match of newdata) {
  console.log(match);
}
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]

// Convert to array
[...newdata];

// Convert to array
Array.from(newdata);
Copy the code

For details, see ES Introduction -matchAll

Dynamic import

The import(specifier) function supports dynamic module loading. The parameter specifier of the import function specifies the location of the module to be loaded. The import() function accepts whatever arguments the import command accepts, mainly because the latter is loaded dynamically.

Import () returns a Promise object

const someVariable = "user";

import(`./some-modules/${someVariable}.js`)
  .then((module) = > {
    // Business logic
    module.loadPageInto(main);
  })
  .catch((err) = > {
    // Failed to load
  });
Copy the code

See ES Getting Started -import for details

Promise.allSettled

The promise.allsettled () method takes a set of Promise instances as parameters, wrapped as a new Promise instance. The wrapping of the instance will not end until all of these parameter instances have returned results, whether fulfilled or rejected

Sometimes, we don’t care about the result of asynchronous requests, only that all requests end. This is where the promise.allsettled () approach comes in handy

const promises = [fetch("index.html"), fetch("https://does-not-exist/")];
const results = await Promise.allSettled(promises);

// Filter out successful requests
const successfulPromises = results.filter((p) = > p.status === "fulfilled");

// Filter out the failed requests and output the cause
const errors = results
  .filter((p) = > p.status === "rejected")
  .map((p) = > p.reason);
Copy the code

globalThis

Obtaining this for different environments before ES2020 requires the following encapsulation

const getGlobalThis = () = > {
  // In the webworker or service worker
  if (typeofself ! = ="undefined") return self;

  // In the browser
  if (typeof window! = ="undefined") return window;

  / / the Node. Js
  if (typeof global! = ="undefined") return global;

  // A separate JavaScript shell
  if (typeof this! = ="undefined") return this;

  throw new Error("Unable to locate global object");
};
const theGlobalThis = getGlobalThis();

if (typeoftheGlobalThis.setTimeout ! = ="function") {
  // There is no setTimeout method in this environment!
}
Copy the code

Now, globalThis provides a standard way to get the globalThis object (which is the global object itself) in different environments.

if (typeofglobalThis.setTimeout ! = ="function") {
  // There is no setTimeout method in this environment!
}
Copy the code

See MDN-globalThis for details

Nullish Coalescing Operator

In JS,?? Operators are called non-airfreight operators. If the first argument is not null/undefined (there are only two false values here, but the false values in JS include: Undefined undefined undefined undefined undefined undefined undefined undefined null object NULL, numeric 0, empty number NaN, Boolean false, empty string ”, don’t confuse) returns the first argument, otherwise returns the second argument. For instance,

null ?? 5; / / = > 5
3 ?? 5; / / = > 3
Copy the code

To the variable to set the default value, the commonly used before | | the Boolean or operator, for example,

const prevMoney = 1;
const currMoney = 0;
const noAccount = null;
const futureMoney = -1;
function moneyAmount(money) {
  return money || 'Account not open';
}
console.log(moneyAmount(prevMoney)); / / = > 1
console.log(moneyAmount(currMoney)); // => The account is not open
console.log(moneyAmount(noAccount)); // => The account is not open
console.log(moneyAmount(futureMoney)); / / = > 1
Copy the code

Above we created the function moneyAmount, which returns the current user balance. We use the | | operator to identify without the users account. However, what does that mean when the user doesn’t have an account? It is more accurate to think of no account as empty rather than zero, since bank accounts may have no (or negative) money. In the example above, the | | operator to zero as a false value, should not include user account $0. Let’s use?? Non-airfreight operators to solve this problem:

const currMoney = 0;
const noAccount = null;
function moneyAmount(money) {
  return money ?? 'Account not open';
}
moneyAmount(currMoney); / / = > 0
moneyAmount(noAccount); // => 'The account is not open'
Copy the code

To sum up…? Operator allows us to specify default values while ignoring error values such as 0 and empty strings.

The Optional Chaining operator

? .Also called chain judgment operator. It allows developers to read property values deeply nested in a chain of objects without having to validate each reference. When the reference is null, the expression stops evaluating and returns undefined. Such as:

var travelPlans = {
  destination: "DC".monday: {
    location: "National Mall".budget: 200,}};console.log(travelPlans.tuesday? .location);// => undefined
Copy the code

Now, put together what we’ve just learned

function addPlansWhenUndefined(plans, location, budget) {
  if(plans.tuesday? .location ==undefined) {
    var newPlans = {
      plans,
      tuesday: {
        location: location ?? "Park".budget: budget ?? 200,}}; }else{ newPlans ?? = plans;// Overwrite only if newPlans is undefined
    console.log("Scheduled Plan");
  }
  return newPlans;
}
// The initial value of the travelPlans object, from the example above
var newPlans = addPlansWhenUndefined(travelPlans, "Ford theater".null);
console.log(newPlans);
// => { plans:
// { destination: 'DC',
// Monday: {location: 'National Mall ', budget: 200}},
// Tuesday: {location: 'Ford theatre ', budget: 200}}
newPlans = addPlansWhenUndefined(newPlans, null.null);
// logs => Scheduled
// returns => newPlans object
Copy the code

The example above contains all the operators we have learned so far. We have now created a function that adds the plan to the object Tuesday. Location, which currently has no nested properties. We also used the non-airfreight operator to provide default values. This function will mistakenly accept a value like “0” as a valid argument. This means that budget can be set to zero without any errors.

BigInt primitive type

In the old version of JS standard, the maximum integer can only be 253-1. Now, BigInt is used to represent the integer. There is no restriction on the number of digits, and any number of digits can be accurately represented. This is another data type in ECMAScript.

You can define a BigInt by adding n to an integer literal, such as 10n, or by calling the function BigInt().

const theBiggestInt = 9007199254740991n;

const alsoHuge = BigInt(9007199254740991);
/ / ↪ 9007199254740991 n
Copy the code
  • Introduction to ES – BigInt

ES2019-ES10

Array#{flat,flatMap}

The members of an Array are sometimes arrays, and array.prototype.flat () is used to “flaten” a nested Array into a one-dimensional Array. This method returns a new array with no effect on the original data.

[1.2[3.4]].flat();
// [1, 2, 3, 4]
Copy the code

FlatMap () can only expand one level of an array.

// Equivalent to [[[2]], [[4]], [[6]], [[8]].flat()
[1.2.3.4].flatMap((x) = > [[x * 2]]);
// [[2], [4], [6], [8]
Copy the code

Refer to ES Introduction – Flat for details

Object.fromEntries

The object.fromentries () method is the reverse of object.entries () and is used to convert an array of key-value pairs into an Object.

Object.fromEntries([
  ["foo"."bar"],
  ["baz".42]]);// { foo: "bar", baz: 42 }
Copy the code

The main purpose of this method is to restore the data structure of the key-value pair to an object, so it is particularly suitable for converting Map structures to objects.

/ / a
const entries = new Map([["foo"."bar"],
  ["baz".42]]);Object.fromEntries(entries);
// { foo: "bar", baz: 42 }

/ / two cases
const map = new Map().set("foo".true).set("bar".false);
Object.fromEntries(map);
// { foo: true, bar: false }
Copy the code

String#{trimStart,trimEnd}

ES2019 adds trimStart() and trimEnd() methods to string instances. They behave the same as trim(), with trimStart() eliminating whitespace at the head of the string and trimEnd() eliminating whitespace at the tail. They all return the new string, not the original string.

const s = " abc ";

s.trim(); // "abc"
s.trimStart(); // "abc "
s.trimEnd(); // " abc"
Copy the code

Symbol#description

ES2019 provides an instance attribute, description, that directly returns a description of the Symbol.

// When creating a Symbol, you can add a description.
const sym = Symbol("foo");

sym.description; // "foo"
Copy the code

In the above code, the description of sym is the string foo.

try { } catch {} // optional binding

Older versions of try/catch statements require a variable for the catch clause. We can leave it out now

/ / the old version
try {
  console.log(a);
} catch (error) {
  console.log("There was an error.");
}

// ES2019-SE10
try {
  console.log(a);
} catch {
  console.log("There was an error.");
}
Copy the code

U + 2028 and U + 2029

In versions prior to ES2019, unescaped is not accepted

  • Line separatorsU + 2028
  • Paragraph separatorU + 2029

ES2019 allows JavaScript strings to be typed directly with U+2028 (line separator) and U+2029 (segment separator).

/* before ES2019, the following code will not report an error. * /
const PS = eval("'\u2029'");
Copy the code

ES Entry -U+2028 and U+2029

JSON – stringify – transformation

To ensure that a valid UTF-8 character is returned, ES2019 changes the behavior of json.stringify (). If a single code point between 0xD800 and 0xDFFF is encountered, or if a pair form does not exist, it returns an escape string, leaving the application to decide what to do next.

JSON.stringify("\u{D834}"); // ""\\uD834""
JSON.stringify("\uDF06\uD834"); // ""\\udf06\\ud834""
Copy the code

ES Getting Started – json-stringify – transformation

Array.prototype.sort() stable sort

Earlier ECMAScript did not specify whether the default sorting algorithm for array.prototype.sort () was stable or not, leaving it up to the browser to decide, which resulted in some implementations being unstable. ES2019 specifies that the default sorting algorithm for array.prototype.sort () must be stable. This has been done, and the default sorting algorithms of all major implementations of JavaScript are now stable.

const arr = ["peach"."straw"."apple"."spork"];

const stableSorting = (s1, s2) = > {
  if (s1[0] < s2[0]) return -1;
  return 1;
};

arr.sort(stableSorting);
// ["apple", "peach", "straw", "spork"]
Copy the code

ES Introduction – Sort stability

revised Function#toString

ES2019 makes changes to the toString() method for function instances.

The toString() method returns the function code itself, previously omitting comments and whitespace.

function/ *foo comment* /foo() {}

/ / the old version
foo.toString();
// function foo() {}

/ / the new
foo.toString();
// "function /* foo comment */ foo () {}"
Copy the code

ES2018-ES9

The template literal restriction is lifted.

ES2018 loosens the restrictions on string escapes in tag templates. If an illegal string escape is encountered, undefined is returned instead of an error, and the raw string is retrieved from the RAW property.

function tag(strs) {
  strs[0= = =undefined
  strs.raw[0= = ="\\unicode and \\u{55}";
}
tag`\unicode and \u{55}`
Copy the code

The JavaScript engine sets the first character to undefined, but the raw property still returns the original string, so the tag function can still handle the original string.

  • Getting Started – Limits on template strings
  • Introduction to ES – row
  • Introduction to ES – modifier: u

Regular s modifier: dotAll pattern -(S (dotAll) flag for regular expressions).

ES2018 introduces the S modifier to make. Can match any single character.

/foo.bar/s.test("foo\nbar"); // true
Copy the code

This is called the dotAll pattern, where dot represents all characters. Therefore, the regular expression also introduces a dotAll attribute that returns a Boolean value indicating whether the regular expression is in dotAll mode.

ES Entry – modifier: dotAll pattern

RegExp named Capture Groups

ES2018 introduces Named Capture Groups, which allows you to specify a name for each group match, making it easy to read code and reference.

const RE_DATE = / (? 
      
       \d{4})-(? 
       
        \d{2})-(? 
        
         \d{2})/
        ;

const matchObj = RE_DATE.exec("1999-12-31");
const year = matchObj.groups.year; / / "1999"
const month = matchObj.groups.month; / / "12"
const day = matchObj.groups.day; / / "31"
Copy the code

ES Getting Started – modifier: Named group matching

Rest/Spread Properties.

ES6 introduced extended operators for arrays,

In ES2018, this writing has also been introduced for objects

const obj = { a: "a".b: "b".c: "c".d: "d".e: "e" };

// Object structure
const{ a, b, c, ... rest } = obj;// Create a new object
constnewObj = { a, ... rest };Copy the code

Assertions after regular line Assertions (RegExp Lookbehind Assertions.)

ES2018 introduces post-line assertions

A “back line assertion” means that x matches only if it does not follow y and must be written as /(?

/ (? <=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // [" 100 "] /(? <! \$)\d+/.exec('it's worth about €90') // / "90"Copy the code

String replacement with a back-line assertion.

const RE_DOLLAR_PREFIX = / (? <=\$)foo/g;
"$foo %foo foo".replace(RE_DOLLAR_PREFIX, "bar");
// '$bar %foo foo'
Copy the code

Getting Started with ES – Assertion after line

Unicode Property Escapes RegExp Unicode Property Escapes

ES2018 introduces a new way to write classes \p{… } and \ {P… } to allow a regular expression to match all characters that match a certain attribute of Unicode.

const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test("PI"); // true

// Matches all Spaces
const reg = /\p{White_Space}/;

// Match all arrow characters
const regexArrows = /^\p{Block=Arrows}+$/u;
regexArrows.test("Please write - left ↔ ↕ ↖ ↗ ↘ ↙ ⇏ ⇐ ⇑ ⇒ ⇓ as indicated by ⇕ ⇖ ⇗ ⇘ ⇙ ⇧ ⇩"); // true
Copy the code

ES Getting Started -Unicode properties class

Promise.prototype.finally.

The finally() method is used to specify the action that will be performed regardless of the final state of the Promise object. This approach was introduced as a standard by ES2018.

promise
.then(result= >{...}). The catch (error= >{...}). Finally,() = > {···});
Copy the code

In the above code, the finally callback is executed after the then or catch callback, regardless of the final state of the promise.

Introduction to ES – finally

Complete Asynchronous Iteration in sequence

In practice, you often encounter a set of asynchronous operations that need to be completed sequentially. For example, you could remotely read a set of urls in sequence and then print the results in the order they were read.

async function logInOrder(urls) {
  // Read the remote URL concurrently
  const textPromises = urls.map(async (url) => {
    const response = await fetch(url);
    return response.text();
  });

  // Output in sequence
  for (const textPromise of textPromises) {
    console.log(awaittextPromise); }}Copy the code
async function getData() {
  const promises = [fetch("url1"), fetch("url2"), fetch("url3"), fetch("url4")];
  for (const item of promises) {
    // Print the promise
    console.log(item);
  }

  for await (const item of promises) {
    // Print the result of the request
    console.log(item); }}Copy the code

ES Getting Started – Sequential asynchronous operations


ES2017-ES8

Object.values/Object.entries

The object. values method returns an array of keys for all the enumerable properties of the argument Object itself (not inherited).

const obj = { foo: "bar".baz: 42 };
Object.values(obj);
// ["bar", 42]

const obj = { 100: "a".2: "b".7: "c" };
Object.values(obj);
// ["b", "c", "a"]
Copy the code

The object. entries method returns an array of all the enumerable key-value pairs that belong to the argument Object itself.

const obj = { foo: "bar".baz: 42 };
Object.entries(obj);
// [ ["foo", "bar"], ["baz", 42] ]
Copy the code

The basic purpose of object. entries is to traverse the properties of objects.

let obj = { one: 1.two: 2 };
for (let [k, v] of Object.entries(obj)) {
  console.log(`The ${JSON.stringify(k)}: The ${JSON.stringify(v)}`);
}
// "one": 1
// "two": 2
Copy the code

The object. entries method is also used to convert objects into real Map structures.

const obj = { foo: "bar".baz: 42 };
const map = new Map(Object.entries(obj));
map; // Map { foo: "bar", baz: 42 }
Copy the code

String padding

ES2017 introduces the string completion length feature. If a string is not long enough to specify, it is completed at the head or tail. PadStart () is used for head completion, and padEnd() is used for tail completion.

"x".padStart(5."ab"); // 'ababx'
"x".padStart(4."ab"); // 'abax'

"x".padEnd(5."ab"); // 'xabab'
"x".padEnd(4."ab"); // 'xaba'
Copy the code

A common use of padStart() is to specify bits for numeric completion. The following code generates a 10-bit numeric string.

"1".padStart(10."0"); / / "0000000001"
"12".padStart(10."0"); / / "0000000012"
"123456".padStart(10."0"); / / "0000123456"
Copy the code

Another use is to prompt the string format.

"12".padStart(10."YYYY-MM-DD"); // "YYYY-MM-12"
"09-12".padStart(10."YYYY-MM-DD"); // "YYYY-09-12"
Copy the code

Object.getOwnPropertyDescriptors

ES2017 introduced Object. GetOwnPropertyDescriptors () method, which returns the specified all its attributes (not inherit property) a description of the Object.

  • value– The actual value of the attribute
  • writable– Whether the value of the attribute can be modified
  • get– Get function, which is called when a property is read
  • set– Set function, which is called when a property is written
  • configurable– Whether the property can be deleted and redefined by delete, whether its specificity can be modified, and whether it can be changed to an accessor property
  • enumerable– Whether the property can be returned through a for-in loop
const obj = {
  foo: 123.get bar() {
    return "abc"; }};Object.getOwnPropertyDescriptors(obj);
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: get bar],
// set: undefined,
// enumerable: true,
// configurable: true } }
Copy the code

This method was introduced to solve the problem that object.assign () cannot copy the get and set properties correctly.

Object. GetOwnPropertyDescriptors () method is another useful, is cooperating with the Object. The create () method, the Object attribute cloned into a new Object. This is a shallow copy.

const shallowClone = (obj) = >
  Object.create(
    Object.getPrototypeOf(obj),
    Object.getOwnPropertyDescriptors(obj),
  );
Copy the code

ES introductory tutorial – getOwnPropertyDescriptors more detailed reference

Trailing comma for function arguments

ES2017 allows functions to have a trailing comma as the last parameter.

Previously, functions were defined and called without allowing a comma after the last argument.

function clownsEverywhere(param1, param2,) {
  / *... * /
}

clownsEverywhere("foo"."bar",);
Copy the code

For more details, see the ES Introduction tutorial – Trailing commas for function arguments

Async functions

The ES2017 standard introduces async functions to make asynchronous operations easier.

What is an async function? In short, it is the syntactic sugar for Generator functions.

function fakeRequest() {
  return new Promise((resolve, reject) = > {
    setTimeout(() = > {
      resolve("Request successful");
    }, 2000);
  });
}

async function getData() {
  console.log("start");
  const res = await fakeRequest();
  console.log(res);
  console.log("end");
}
getData();
2. The request succeeded 3. End */
Copy the code

Use Atomics to share memory

The Atomics object provides a set of static methods to operate atomically on SharedArrayBuffer and ArrayBuffer objects.

See MDN-Atomics for more details


ES2016-ES7

Array.prototype.includes

The array.prototype. includes method returns a Boolean value indicating whether an Array contains the given value, similar to the string includes method.

[1.2.3]
  .includes(2) // true
  [(1.2.3)].includes(4) // false
  [(1.2.NaN)].includes(NaN); // true
Copy the code

Exponentiation operator

// 2 squared
2六四事件2; / / 4
// 2 to the third
2六四事件3; / / 8
Copy the code

See the ES Introduction tutorial – Exponential Operators for more details


ES2015-ES6

Recommend Ruan Yifeng big guy’s ES introduction tutorial, The Chinese document has no more detailed than him

Arrows function (ARROWS)

Arrow functions are shorthand for functions that use => syntax. What’s different from a normal function

  1. Functional in vivothisAn object is an object that is defined, not used.
  • The point of the this object is mutable, but in the arrow function, it is fixed.
  1. It cannot be used as a constructor, that is, it cannot be usednewCommand, or an error will be thrown.
  2. Do not useargumentsObject that does not exist in the function body. You can use it if you wantrestParameter instead.
  3. Do not useyieldCommand, so the arrow function cannot be used as a Generator function.
var f = (v) = > v;

/ / is equivalent to
var f = function (v) {
  return v;
};

function foo() {
  setTimeout(() = > {
    console.log("id:".this.id);
  }, 100);
}

var id = 21;
// The arrow function causes this to always refer to the object ({id: 42}) where the function definition was in effect, so 42 is printed
foo.call({ id: 42 });
// id: 42

// Objects do not constitute a separate scope, making this point to a global object
globalThis.s = 21;
const obj = {
  s: 42.m: () = > console.log(this.s),
};

obj.m(); / / 21
Copy the code

See the ES Introduction tutorial – Arrow functions for more details

Class (Class)

// ES5
function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return "(" + this.x + "," + this.y + ")";
};

var p = new Point(1.2);

// ES6
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return "(" + this.x + "," + this.y + ")"; }}Copy the code

For more details, see the ES Introduction tutorial -Class

Enhanced Object Literals

A concise representation of the properties of an object

const foo = "bar";
const method = function () {
  return "Hello!";
};

const filed = "name";

const baz = {
  foo,
  method,
  [filed]: "Wang"};/ / is equivalent to
const baz = {
  foo: foo,
  method: function () {
    return "Hello!";
  },
  name: "Wang"};Copy the code

For more details, see the ES Getting Started tutorial – Object Extensions

Template string

// Insert variables into the string
let name = "Bob",
  time = "today";
`Hello ${name}, how are you ${time}? `;
Copy the code

See the ES Getting Started tutorial – String Templates for more details

Array deconstruction + extension operator

var [a] = [];

a === undefined; // true

var [a = 1] = [];
a === 1; // true
Copy the code

For more details, see the ES Introduction tutorial – Extension operators for arrays

Function default argument + remaining argument + extension operator

// If y is not passed or y===undefined, then y=12
function f(x, y = 12) {
  return x + y;
}
f(3) = =15;
Copy the code
function f(x, ... y) {
  // Y is an array
  return x * y.length;
}
f(3."hello".true) = =6;
Copy the code
function f(x, y, z) {
  return x + y + z;
}
// Pass each elem of array as argumentf(... [1.2.3= =])6;
Copy the code

For more details, see the ES Getting Started tutorial – Function Default arguments

Block-level scoped variables

With the introduction of the let/const keyword in ES6, JS has function scope and global scope. Now JS can also have block-level scope.

function f() {{let x;
    {
      // Normal, because it is in a new block-level scope
      const x = "sneaky";
      // The const definition cannot be modified, so an error is reported
      x = "foo";
    }
    X is declared in the block-level scope, so an error is reported
    let x = "inner"; }}Copy the code

For more details, see the ES Introduction tutorial – Unicode

Traversal/iterator +for.. of(iterators + for.. of)

A data structure that deploys the Symbol. Iterator property is considered to have an iterator interface and can be used for… The of loop iterates through its members. That is to say, for… Inside the of loop, the Symbol. Iterator method of the data structure is called.

for … Of is for… An alternative to in and forEach(), which loops through iterable data structures such as arrays, maps, collections, and strings.

JavaScript for… In loop, can only get the key name of the object, cannot directly get the key value. ES6 provided for… Of loop, allowing you to iterate to get the key.

var arr = ["a"."b"."c"."d"];

for (let a in arr) {
  console.log(a); // 0 1 2 3
}

for (let a of arr) {
  console.log(a); // a b c d
}

const str = "helloworld";
for (let a of str) {
  console.log(a); // h e l l o w o r l d
}
Copy the code

For more details, see the ES Introduction tutorial – Iterators

Generator (generators)

Generators simplify the creation of iterators with function * and yield. A function declared as function * is a iterator object, that is, a Generator function is a iterator object Generator function. The iterator object that is returned iterates through each state inside the Generator function in turn.

Generators are subtypes of iterators and therefore have next and throw methods.

The yield expression is the flag that suspends execution, while the next method can resume execution

Note: After ES7 is present, await is recommended.

function* foo() {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
  yield 5;
  return 6;
}

for (let v of foo()) {
  console.log(v);
}
// 1, 2, 3, 4, 5
Copy the code

Here is an example using Generator functions and for… Of loop to implement the Fibonacci sequence.

var fibonacci = {
  [Symbol.iterator]: function* () {
    let [prev, curr] = [0.1];
    for (;;) {
      yieldcurr; [prev, curr] = [curr, prev + curr]; }}};for (var n of fibonacci) {
  //
  if (n > 1000) break;
  console.log(n);
}
Copy the code

As you can see from the above code, use for… You do not need to use the next method for the OF statement.

Use for… Of loop, which can write methods that traverse arbitrary objects. Native JavaScript objects have no iterator interface and cannot use for… The “of” loop can be used by adding this interface to it using the Generator function.

Generators essentially inherit iterators

interface Generator extendsIterator { next(value? :any): IteratorResult;
  throw(exception: any);
}
Copy the code

For more details, see the ES Introduction tutorial – Iterators

Unicode

ES6 provides Unicode enhancements, including

  • Unicode representation of characters is supported

For example, the Unicode code point for “middle” is U+4e2d, and you can either enter the character directly in the string or the escape form \u4e2d, which is equivalent.

"In"= = ="\u4e2d"; // true
Copy the code
  • use/uA regular expression that matches a code point
// New RegExp behaviour, opt-in 'u'
"𠮷".match(/./u) [0].length == 2;
Copy the code
  • Gets the 32-bit utF-16 character code point –codePointAt
"𠮷".codePointAt(0) = =0x20bb7;

let s = "𠮷 a.";
for (let ch of s) {
  console.log(ch.codePointAt(0).toString(16));
}
// 20bb7
/ / 61
Copy the code

For more details, see the ES Introduction tutorial – Unicode

Modular (modules)

ES6 implements modular functionality at the language standard level and is fairly simple enough to replace CommonJS and AMD specifications as a universal modular solution for browsers and servers.

Use export default or export to export

// math.js
export const pi = 3.141593;

export default function sum(x, y) {
  return x + y;
}
Copy the code

Import using import

// app.js
import sum, { pi } from "./math";

alert("Two PI =" + sum(pi, pi));
Copy the code

For more details, see the ES Starting Tutorial – Module

Module loaders rules

Module loaders support:

  • Asynchronous loading
  • Code runs in the module scope, not the global scope. A top-level variable inside a module that is not visible outside.
  • Module, top levelthisThe keyword returns undefined, not pointedwindow. That is, at the module levelthisKeywords are meaningless
//index.js
const x = 1;

console.log(x === window.x); //false
console.log(this= = =undefined); // true
Copy the code

Using the top-level syntax point of this equals undefined, you can detect whether the current code is in the ES6 module.

const isNotModuleScript = this! = =undefined;
Copy the code

For more details, see the ES Getting Started tutorial – Module-loader

import and export

Map + Set + Weakmap + Weakset

ES6 provides a new data structure, Set. It is similar to an array, but the member values are unique and there are no duplicate values.

// Sets
var s = new Set(a); s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") = = =true;
Copy the code

ES6 provides a Map data structure. It is similar to an object in that it is also a collection of key-value pairs, but the range of “keys” is not limited to strings, and all types of values (including objects) can be used as keys. In other words, the Object structure provides a “string value” correspondence, and the Map structure provides a “value value” correspondence, which is a more complete implementation of the Hash structure. If you need a “key-value pair” data structure, Map is more appropriate than Object.

// Maps
var m = new Map(a); m.set("hello".42);
m.set(s, 34);
m.get(s) == 34;
Copy the code

Similar to the Map structure, the WeakMap structure is also used to generate a collection of key and value pairs.

There are two differences between WeakMap and Map.

  1. WeakMap only accepts objects as key names (except null) and does not accept other types of values as key names.
  2. The object pointed to by the key name of a WeakMap is not included in the garbage collection mechanism.
// Weak Maps
var wm = new WeakMap(a); wm.set(s, {extra: 42 });
wm.size === undefined;
Copy the code

The structure of a WeakSet is similar to a Set in that it is a collection of non-repeating values. However, it differs from Set in two ways.

  1. Members of a WeakSet can only be objects and not values of other types.
  2. Objects in a WeakSet are weak references
// Weak Sets
var ws = new WeakSet(a); ws.add({data: 42 });
// Because the added object has no other references, it will not be held in the set
Copy the code

See the ES Primer -Set and Map for more details

The agent (proxies)

Proxy is used to modify the default behavior of certain operations, which is equivalent to making changes at the language level. Can be used for operational interception, logging/analysis, etc.

// Proxy a common object
var target = {};
var handler = {
  get: function (receiver, name) {
    return `Hello, ${name}! `; }};var p = new Proxy(target, handler);

// true
p.world === "Hello, world!";
Copy the code

Here are all the “meta-operations” that Proxy can Proxy

var handler =
{
  get:... .set:... .has:... .deleteProperty:... .apply:... .construct:... .getOwnPropertyDescriptor:... .defineProperty:... .getPrototypeOf:... .setPrototypeOf:... .enumerate:... .ownKeys:... .preventExtensions:... .isExtensible:...
}
Copy the code

MDN-handler.get()

// Proxy a function object
var target = function () {
  return "I am the target";
};
var handler = {
  apply: function (receiver, ... args) {
    return "I am the proxy"; }};var p = new Proxy(target, handler);
//true
p() === "I am the proxy";
Copy the code

See the ES Proxy tutorial for more details

symbols

ES6 introduces a new primitive data type, Symbol, which represents unique values

The Symbol value is generated by the Symbol function. This means that object attribute names can now have two types: one is an existing string and the other is the new Symbol type. Attribute names that are of type Symbol are unique and are guaranteed not to conflict with other attribute names.

var MyClass = (function () {
  //
  var key = Symbol("key");

  function MyClass(privateData) {
    this[key] = privateData;
  }

  MyClass.prototype = {
    doStuff: function () {
      this[key]; }};returnMyClass; }) ();var c = new MyClass("hello");
// true
console.log(c["key"= = =undefined);
Copy the code

When creating a Symbol, you can add a description.

const sym = Symbol("foo");
Copy the code

In the above code, the description of sym is the string foo.

Symbol is the name of the property that does not appear in the for… In, for… Of loop, will not be the Object. The keys (), Object, getOwnPropertyNames (), JSON. The stringify () returns.

However, it is not private property, with an Object. The getOwnPropertySymbols () method, which can get all the Symbol of specified Object attribute names. This method returns an array of all the Symbol values for the current object that are used as attribute names.

const obj = {};
let a = Symbol("a");
let b = Symbol("b");

obj[a] = "Hello";
obj[b] = "World";

const objectSymbols = Object.getOwnPropertySymbols(obj);

objectSymbols;
// [Symbol(a), Symbol(b)]
Copy the code

See the ES Introduction tutorial – Symbol for more details

Futures (promises)

Promise is a library for asynchronous programming that holds the results of an event (usually an asynchronous operation) that ends in the future. Many existing JavaScript libraries already use Promise.

function timeout(duration = 0) {
  return new Promise((resolve, reject) = > {
    setTimeout(resolve, duration);
  });
}

var p = timeout(1000)
  .then(() = > {
    return timeout(2000);
  })
  .then(() = > {
    throw new Error("hmm");
  })
  .catch((err) = > {
    return Promise.all([timeout(100), timeout(200)]);
  });
Copy the code

See the ES Starter tutorial – Promise for more details

math + number + string + array + object APIs

Added many types of extension methods, including :Math,Array,String,Object

Number.EPSILON;
Number.isInteger(Infinity); // false
Number.isNaN("NaN"); // false

Math.acosh(3); / / 1.762747174039086
Math.hypot(3.4); / / 5
Math.imul(Math.pow(2.32) - 1.Math.pow(2.32) - 2); / / 2

"abcde".includes("cd"); // true
"abc".repeat(3); // "abcabcabc"

Array.from(document.querySelectorAll("*")); // Returns a real Array
Array.of(1.2.3) // Similar to new Array(...) , but without special one-arg behavior
  [(0.0.0)].fill(7.1) / /,7,7 [0]
  [(1.2.3)].find((x) = > x == 3) / / 3
  [(1.2.3)].findIndex((x) = > x == 2) / / 1
  [(1.2.3.4.5)].copyWithin(3.0) // [1, 2, 3, 1, 2]
  [("a"."b"."c")].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
  [("a"."b"."c")].keys() // iterator 0, 1, 2
  [("a"."b"."c")].values(); // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0.0)});Copy the code

For more details, see the ES Introduction tutorial:

  • Number
  • Math,
  • Array.from
  • Array.of
  • Array.prototype.copyWithin
  • Object.assign

Binary and Octal literals

Two new digital representations.

  • Binary: starts with 0b
  • Octal: starts with 0o
0b111110111= = =503; // true
0o767= = =503; // true
Copy the code

reflect api

The Reflect API exposes runtime level meta-operations on objects.

The most important purpose is to use it with a Proxy to perform native behavior

Make all Object operations function behavior. Some Object operations are imperative, such as name in obj and delete obj[name], while reflect.has (obj, name) and reflect.deleteProperty (obj, name) make them functional behavior.

/ / the old way
"assign" in Object; // true

/ / a new way
Reflect.has(Object."assign"); // true
Copy the code

See the ES Introduction tutorial – Reflect for more details

Tail calls

  • Tail call: The last step of a function is to return and call another function
  • Tail recursion: The function call itself, called recursion. If the tail calls itself, it is called tail recursion.
  • Tail call optimization

Note that tail call optimization is currently only supported in Safari, not Chrome or Firefox. I won’t delve into it here 😁

function factorial(n, acc = 1) {
  if (n <= 1) return acc;
  return factorial(n - 1, n * acc);
}

// Most browsers have a stack overflow error,
// But it is safe in ES6 Safari
factorial(100000);
Copy the code

For more details, see the ES Getting Started tutorial – Tail calls

Internationalize strings, numbers, and dates through the Intl API

The Intl object is the namespace of the ECMAScript internationalization API and provides language sensitive string comparisons, support for numeric formatting, and date and time formatting.

Intl. Collator object

The word collator means sort. The Intl.Collator object is the constructor of a Collator that supports language-sensitive string comparisons.

  • Chinese sorting

What if we want our Chinese to be sorted in alphabetical order?

In this case, you can use the BCF 47 language tag string zh in simplified Chinese. The code is as follows:

var arrUsername = [
  "Chen"."Deng chao"."Du Chun"."Feng Shaofeng"."Han geng"."Brief"."Huang Xiaoming"."Jia Nailang"."李晨"."Li Yifeng"."Lu Han"."Jing Boran"."Liu ye"."陆毅"."Sun Honglei",]; arrUsername.sort(new Intl.Collator("zh").compare);
/ / the result is: [" Chen ", "deng chao," "Du Chun", "through time and space", "han geng", "brief", "huang xiaoming," "smile", "jingboran", "15", "li yi feng", "liu ye", "lu", "Lu Han", "sun hong2 lei2"]
Copy the code

Intl API details can refer to this article JS Intl object complete introduction and application in Chinese


ES2011-ES5

I believe that you already know the ES5, so I will just make a brief list, not to illustrate

‘USE STRICT’

Earlier versions of JS allowed the use of undeclared variables. However, an error is reported when the ES5 “Use strict” function is used

// index.js
"use strict";

// Error :a is not defined
a = 22;
Copy the code

Array

Array.isArray

Array.forEach

Array.map

Array.filter

Array.reduce

Array.reduceRight

Array.every

Array.some

Array.indexOf

Array.lastIndexOf

JSON

JSON.parse

JSON.stringify

DATE

Date.now()

Date.now().valueOf()

Object.defineProperty()


conclusion

So that’s the end of the EcmaScript walkthrough. Let’s wrap it up with a mind map

Click to view the original mind map

Reference documentation

  1. ECMAScript 6 Features
  2. es6-features.org
  3. ES2021 Features with simple examples
  4. Four powerful JavaScript operators
  5. ES6 core features