Inventory ES7, ES8, ES9, ES10 новые функции

внешний интерфейс JavaScript

предисловие

Начиная с ECMAScript 2016 (ES7) выпуски версий стали более частыми, и каждый год выходит новая версия.К счастью, обновлений в каждой версии не так много.В этой статье будут подробно рассмотрены эти новые возможности, максимально связанные со старыми знания, чтобы помочь вам быстро начать работу с этими функциями.Чтобы прочитать больше качественных статей, нажмитеБлог GitHub

Что нового в ES7

1.Метод Array.prototype.includes()

В ES6 у нас есть String.prototype.includes(), который может запрашивать, содержит ли данная строка символ, а в ES7 мы также можем использовать метод Array.prototype.includes в массиве, чтобы определить, содержит ли массив указанный символ. , соответственно, возвращает true, если он включен, и false в противном случае.

const arr = [1, 3, 5, 2, '8', NaN, -0]
arr.includes(1) // true
arr.includes(1, 2) // false 该方法的第二个参数表示搜索的起始位置,默认为0
arr.includes('1') // false
arr.includes(NaN) // true
arr.includes(+0) // true

До ES7, если вы хотели определить, содержит ли массив элемент, существовало два следующих метода, но ни один из них не был таким интуитивным, как включение:

  • indexOf()

Метод indexOf() возвращает первый индекс в массиве, по которому можно найти данный элемент, или -1, если он не существует.

if (arr.indexOf(el) !== -1) {
  // ...
}

Однако у этого метода есть два недостатка: во-первых, он недостаточно семантичен, необходимо найти позицию первого вхождения значения параметра, поэтому недостаточно интуитивно сравнивать, не равно ли оно -1. Во-вторых, он использует оператор строгого равенства (===) внутри для оценки, что приведет к неправильной оценке NaN.

[NaN].indexOf(NaN)// -1
  • найти() и найтииндекс()

Метод find экземпляра массива используется для поиска первого подходящего члена массива. Кроме того, оба метода могут находить NaN, что компенсирует отсутствие метода indexOf у массива.

[1, 4, -5, 10].find((n) => n < 0) // -5
[1, 5, 10, 15].findIndex(function(value) {
  return value > 9;
}) // 2
[NaN].findIndex(y => Object.is(NaN, y)) // 0

Поддержка Array.prototype.includes():

2. Оператор возведения в степень**

Оператор экспоненты был введен в ES7 с эквивалентом Math.pow().

console.log(2**10);// 输出1024
console.log(Math.pow(2, 10)) // 输出1024

Поддержка операторов возведения в степень:

Новые функции ES8

1.Async/Await

Все мы знаем, что использование промисов может хорошо решить проблему ада обратных вызовов, но если поток обработки сложен, то весь код будет заполнен тогда, семантика не очевидна, и код не может хорошо представить поток выполнения. есть лучший способ сделать это?Как насчет более элегантного асинхронного способа промисов?

Предположим, есть такой сценарий использования: вам нужно сначала запросить ссылку, а затем после возврата информации запросить другой ресурс, связанный с b. В следующем коде показано использование выборки для выполнения такого требования, выборка определена в объекте окна и возвращает объект Promise.

fetch('https://blog.csdn.net/')
  .then(response => {
    console.log(response)
    return fetch('https://juejin.cn')
  })
  .then(response => {
    console.log(response)
  })
  .catch(error => {
    console.log(error)
  })

Хотя приведенный выше код может удовлетворить это требование, семантика не очевидна, и код не может правильно представить поток выполнения. По этой причине в ES8 был представлен async/await, который является значительным улучшением асинхронного программирования на JavaScript, предоставляя возможность использовать синхронный код для асинхронного доступа к ресурсам без блокировки основного потока и делая логику кода более понятной.

async function foo () {
  try {
    let response1 = await fetch('https://blog.csdn.net/')
    console.log(response1)
    let response2 = await fetch('https://juejin.cn')
    console.log(response2)
  } catch (err) {
    console.error(err)
  }
}
foo()

В приведенном выше коде вы обнаружите, что вся логика асинхронной обработки реализована с использованием синхронного кода, а также поддерживает исключения try catch to catch Это похоже на написание синхронного кода, поэтому он очень согласуется с человеческим линейным мышлением. Следует подчеркнуть, что,await нельзя использовать независимо от async, за ожиданием должен следовать объект Promise, в противном случае он будет автоматически заключен в объект Promise.

Согласно определению MDN,async — это функция, которая выполняется асинхронно и в результате неявно возвращает промис..

async function foo () {
  return '浪里行舟'
}
foo().then(val => {
  console.log(val) // 浪里行舟
})

В приведенном выше коде мы видим, что вызов функции foo, объявленной async, возвращает объект Promise, что эквивалентно следующему коду:

async function foo () {
  return Promise.resolve('浪里行舟')
}
foo().then(val => {
  console.log(val) // 浪里行舟
})

Поддержка асинхронного/ожидания:

2.Object.values(), Object.entries()

В ES5 представлен метод Object.keys, который возвращает массив, элементами которого являются ключи всех перечислимых свойств самого объекта параметра (за исключением унаследованных). ES8 представил Object.values ​​и Object.entries, которые сопоставляются с Object.keys, в качестве дополнительных средств обхода объекта для цикла for...of.

Метод Object.values ​​возвращает массив, элементами которого являются ключи всех перечисляемых свойств самого объекта параметра (исключая унаследованные).

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"]

должны знать о том,Если имя атрибута является числовым атрибутом, он проходится в соответствии с числовым значением, от меньшего к большему., поэтому возвращаемый порядок равен b, c, a.

Метод Object.entries() возвращает массив пар ключ-значение всех перечислимых свойств самого объекта параметра (за исключением унаследованных). Эта функция будет упомянута позже, когда мы представим Object.fromEntries() из ES10.

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.entries(obj); // [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]

Object.values() совместим с Object.entries().В следующем примере используется Object.values():

3.String padding

Две новые функции экземпляра String.prototype.padStart и String.prototype.padEnd были добавлены к String в ES8, позволяя добавлять пустые строки или другие строки в начало или конец исходной строки. Давайте сначала посмотрим на синтаксис:

String.padStart(targetLength,[padString])
  • targetLength (обязательно): целевая длина, до которой необходимо дополнить текущую строку. Если это значение меньше длины текущей строки, возвращается сама текущая строка.
  • padString (необязательно): строка заполнения. Если строка слишком длинная и длина дополненной строки превышает целевую длину, будет сохранена только самая левая часть, а остальные части будут усечены.Значение этого параметра по умолчанию — " ".
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'

Иногда нам часто нужно форматировать при работе с датами и суммами, и эта функция пригодится:

'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

Поддержка заполнения строки:

4.Object.getOwnPropertyDescriptors()

Метод Object.getOwnPropertyDescriptor() в ES5 возвращает дескриптор свойства объекта. В ES8 представлен метод Object.getOwnPropertyDescriptors(), который возвращает объект описания всех его собственных свойств (не унаследованных свойств) указанного объекта.

const obj = {
  name: '浪里行舟',
  get bar () {
    return 'abc'
  }
}
console.log(Object.getOwnPropertyDescriptors(obj))

Получил следующий результат:Цель этого метода в основном состоит в том, чтобы решить проблему, заключающуюся в том, что Object.assign() не может скопировать атрибут get и правильно установить атрибут. Давайте посмотрим на пример:

const source = {
  set foo (value) {
    console.log(value)
  },
  get bar () {
    return '浪里行舟'
  }
}
const target1 = {}
Object.assign(target1, source)
console.log(Object.getOwnPropertyDescriptor(target1, 'foo'))

Возвращает следующие результаты:

В приведенном выше коде значение свойства foo исходного объекта является функцией присваивания, метод Object.assign копирует это свойство в объект target1, и в результате значение свойства становится неопределенным. Это потому чтоМетод Object.assign всегда копирует значение свойства, а не присваивание или метод получения, стоящий за ним..

В настоящее время метод Object.getOwnPropertyDescriptors() взаимодействует с методом Object.defineProperties() для обеспечения правильного копирования.

const source = {
  set foo (value) {
    console.log(value)
  },
  get bar () {
    return '浪里行舟'
  }
}
const target2 = {}
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source))
console.log(Object.getOwnPropertyDescriptor(target2, 'foo'))

Возвращает следующие результаты:

Поддержка Object.getOwnPropertyDescriptors():

Что нового в ES9

1.for await of

Метод for of может проходить данные синхронного итератора с интерфейсом Symbol.iterator, но не может проходить асинхронные итераторы. Новый for await of ES9 может использоваться для обхода структуры данных с помощью метода Symbol.asyncIterator, то есть асинхронного итератора, и будет ожидать изменения состояния предыдущего члена перед переходом к следующему члену, что эквивалентно внутренняя асинхронная функция. Теперь у нас есть три асинхронных задачи, и мы хотим последовательно выводить результаты, как это сделать?

// for of遍历
function Gen (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(time)
    }, time)
  })
}
async function test () {
  let arr = [Gen(2000), Gen(100), Gen(3000)]
  for (let item of arr) {
    console.log(Date.now(), item.then(console.log))
  }
}
test()

Получил следующий результат:

Приведенный выше код подтверждает, что метод for of не может пройти через асинхронный итератор, и полученный результат не соответствует нашим ожиданиям, поэтому for await of выходит на сцену!

function Gen (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(time)
    }, time)
  })
}
async function test () {
  let arr = [Gen(2000), Gen(100), Gen(3000)]
  for await (let item of arr) {
    console.log(Date.now(), item)
  }
}
test()
// 1575536194608 2000
// 1575536194608 100
// 1575536195608 3000

При использовании for await of traversal он будет ждать изменения состояния предыдущего объекта Promise перед переходом к следующему члену.

Поддержка асинхронных итераторов:

2.Object Rest Spread

Одной из самых интересных функций, добавленных в ES6, является оператор спреда. Вы можете использовать его не только для замены методов cancat() и slice(), чтобы упростить операции с массивами (копирование, слияние), но оператор распространения также полезен в ситуациях, когда массивы должны быть разделены как параметры функции.

const arr1 = [10, 20, 30];
const copy = [...arr1]; // 复制
console.log(copy);    // [10, 20, 30]
const arr2 = [40, 50];
const merge = [...arr1, ...arr2]; // 合并
console.log(merge);    // [10, 20, 30, 40, 50]
console.log(Math.max(...arr));    // 30 拆解

ES9 расширяет этот синтаксис, добавляя расширенные свойства к литералам объектов. Он может копировать свойства одного объекта в другой объект, обратитесь к следующим случаям:

const input = {
  a: 1,
  b: 2,
  c: 1
}
const output = {
  ...input,
  c: 3
}
console.log(output) // {a: 1, b: 2, c: 3}

Приведенный выше код может добавлять данные входного объекта к выходному объекту.Следует отметить, чтоЕсли такое же имя свойства существует, только последнее вступит в силу.

const input = {
  a: 1,
  b: 2
}
const output = {
  ...input,
  c: 3
}
input.a='浪里行舟'
console.log(input,output) // {a: "浪里行舟", b: 2} {a: 1, b: 2, c: 3}

В приведенном выше примере значение во входном объекте изменяется, но вывод не меняется, что указывает на то, что оператор распространения копирует объект (например, obj2 = {...obj1}),Реализация — это всего лишь неглубокая копия объекта.. Стоит отметить, что если значением свойства является объект, будет скопирована ссылка на объект:

const obj = {x: {y: 10}};
const copy1 = {...obj};    
const copy2 = {...obj}; 
obj.x.y='浪里行舟'
console.log(copy1,copy2) // x: {y: "浪里行舟"} x: {y: "浪里行舟"}
console.log(copy1.x === copy2.x);    // → true

copy1.x и copy2.x являются ссылками на один и тот же объект, поэтому они строго равны.

Давайте снова посмотрим на пример Object rest:

const input = {
  a: 1,
  b: 2,
  c: 3
}
let { a, ...rest } = input
console.log(a, rest) // 1 {b: 2, c: 3}

Когда ключ-значение объекта является неопределенным, назначьте требуемый ключ переменной и используйте переменную для сведения других необязательных данных ключа, что было невозможно раньше. Уведомление,Атрибут rest всегда должен стоять в конце объекта., иначе будет выброшена ошибка.

Rest совместим с Spread, в качестве примера используется Spread:

3.Promise.prototype.finally()

Метод Promise.prototype.finally() возвращает обещание.В конце выполнения обещания, независимо от того, выполнен результат или отклонен, после выполнения then() и catch() будет выполнена функция обратного вызова, указанная в finally.

fetch('https://www.google.com')
  .then((response) => {
    console.log(response.status);
  })
  .catch((error) => { 
    console.log(error);
  })
  .finally(() => { 
    document.querySelector('#spinner').style.display = 'none';
  });

Метод finally() удобен, когда вам нужно выполнить некоторую очистку после операции, независимо от того, была ли операция успешной или нет. Это дает возможность указать код, который должен быть выполнен после выполнения обещания, независимо от того, выполнен ли результат или отклонен.Избегайте ситуации, когда один и тот же оператор нужно написать по одному разу в then() и catch()..

Поддержка Promise.prototype.finally():

4. Новые функции регулярных выражений

ES9 добавляет к регулярным выражениям четыре новых функции, которые еще больше улучшают возможности обработки строк в JavaScript. Эти особенности заключаются в следующем:

  • флаг s (dotAll)
  • именованная группа захвата
  • Утверждение взгляда назад
  • Экранирование свойства Unicode

(1) флаг s(dotAll)

В регулярных выражениях точка (.) — это специальный символ, представляющий любой отдельный символ, за двумя исключениями. Один из них представляет собой четырехбайтовый символ UTF-16, который можно разрешить с помощью модификатора u; другой — признак конца строки, такой как перевод строки (\n) или возврат каретки (\r), который может быть разрешен с помощью ES9. s(dotAll)flag, добавление s к исходному регулярному выражению означает:

console.log(/foo.bar/.test('foo\nbar')) // false
console.log(/foo.bar/s.test('foo\nbar')) // true

Как определить, использует ли текущее регулярное выражение режим dotAll?

const re = /foo.bar/s // Or, `const re = new RegExp('foo.bar', 's');`.
console.log(re.test('foo\nbar')) // true
console.log(re.dotAll) // true
console.log(re.flags) // 's'

(2) Именованные группы захвата

В некоторых шаблонах регулярных выражений сопоставление с использованием чисел может привести к путанице. Например, используйте регулярное выражение /(\d{4})-(\d{2})-(\d{2})/ для сопоставления дат. Поскольку обозначение даты в американском английском отличается от обозначения даты в британском английском, может быть трудно различить, какая группа представляет день, а какая группа представляет месяц:

const re = /(\d{4})-(\d{2})-(\d{2})/;
const match= re.exec('2019-01-01');
console.log(match[0]);    // → 2019-01-01
console.log(match[1]);    // → 2019
console.log(match[2]);    // → 01
console.log(match[3]);    // → 01

В ES9 введены именованные группы захвата, которые позволяют назначать имя каждому совпадению группы, что упрощает чтение кода и упрощает обращение к нему.

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = re.exec('2019-01-01');
console.log(match.groups);          // → {year: "2019", month: "01", day: "01"}
console.log(match.groups.year);     // → 2019
console.log(match.groups.month);    // → 01
console.log(match.groups.day);      // → 01

В приведенном выше коде «именованная группа захвата» находится внутри круглых скобок, а «вопросительный знак + угловые скобки + имя группы» (?) добавляется к заголовку шаблона, а затем на имя группы можно ссылаться в группах. атрибут результата, возвращаемого методом exec.

Именованные группы захвата также можно использовать в методе replace(), например, для преобразования дат в формат США ММ-ДД-ГГГГ:

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const usDate = '2018-04-30'.replace(re, '$<month>-$<day>-$<year>')
console.log(usDate) // 04-30-2018

(3) Утверждение Lookbehind line-behind

Регулярные выражения языка JavaScript поддерживают только утверждения с опережением, а не утверждения с просмотром назад. Утверждение с просмотром вперед можно просто понимать как «сначала столкнуться с условием, а затем решить, выполняется ли оно позднее», как показано на следующий пример:

let test = 'hello world'
console.log(test.match(/hello(?=\sworld)/))
// ["hello", index: 0, input: "hello world", groups: undefined]

Но иногда мы хотим судить привет перед всем миром, и этот код не может быть реализован. Это ретроспективное утверждение поддерживается в ES9:

let test = 'world hello'
console.log(test.match(/(?<=world\s)hello/))
// ["hello", index: 6, input: "world hello", groups: undefined]

(?, затем объедините = (равно), ! (не равно), \1 (захват совпадения).

(4) Экранирование атрибута Unicode

ES2018 представляет новую нотацию класса \p{...} и \P{...}, которая позволяет регулярным выражениям сопоставлять все символы, соответствующие определенному свойству Unicode. Например, вы можете использовать \p{Number} для сопоставления всех чисел Unicode, например, предположив, что вы хотите сопоставить строку символов Unicode ㉛:

const str = '㉛';
console.log(/\d/u.test(str));    // → false
console.log(/\p{Number}/u.test(str));     // → true

Точно так же вы можете использовать \p{Alphabetic} для соответствия всем символам слова Unicode:

const str = 'ض';
console.log(/\p{Alphabetic}/u.test(str));     // → true
// the \w shorthand cannot match ض
console.log(/\w/u.test(str));    // → false

Также существует отрицательный escape-шаблон свойства Unicode \P{...}

console.log(/\P{Number}/u.test('㉛'));    // → false
console.log(/\P{Number}/u.test('ض'));    // → true
console.log(/\P{Alphabetic}/u.test('㉛'));    // → true
console.log(/\P{Alphabetic}/u.test('ض'));    // → false

В дополнение к буквам и цифрам в escape-последовательности свойств Unicode можно использовать некоторые другие свойства.

Поддержка вышеуказанных функций

Что нового в ES10

1.Array.prototype.flat()

Многомерные массивы — распространенный формат данных, особенно при извлечении данных. Сведение многомерных массивов является распространенным требованием. Обычно мы можем это сделать, но это недостаточно элегантно.

Метод flat() рекурсивно проходит массив до указанной глубины и возвращает все элементы, объединенные с элементами в пройденных подмассивах, в новый массив.

newArray = arr.flat(depth) // depth是指定要提取嵌套数组的结构深度,默认值为 1	

Далее мы рассмотрим два примера:

const numbers1 = [1, 2, [3, 4, [5, 6]]]
console.log(numbers1.flat())// [1, 2, 3, 4, [5, 6]]
const numbers2 = [1, 2, [3, 4, [5, 6]]]
console.log(numbers2.flat(2))// [1, 2, 3, 4, 5, 6]

В приведенных выше двух примерах показано, что параметр flat не установлен, а значение по умолчанию равно 1, что означает, что сглаживается только первый уровень; когда параметр flat больше или равен 2, возвращаемое значение равно [1 , 2, 3, 4, 5, 6].

Поддержка Array.prototype.flat:

2.Array.prototype.flatMap()

С плоским методом, естественно, есть метод Array.prototype.flatMap.Метод flatMap() сначала сопоставляет каждый элемент с помощью функции сопоставления, а затем сжимает результат в новый массив. Также из названия метода видно, что он содержит две функции, одна — map, а другая — flat (глубина 1).

let arr = [1, 2, 3]
console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6]
console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6]

По сути, flatMap представляет собой комбинацию картографических и плоских операций, поэтомуЕго можно только выровнять.

Поддержка Array.prototype.flatmap:

3.Object.fromEntries()

Object.fromEntries Этот новый API реализует противоположность Object.entries. Это упрощает получение объекта на основе его записей.

const object = { x: 23, y:24 };
const entries = Object.entries(object); // [['x', 23], ['y', 24]]
const result = Object.fromEntries(entries); // { x: 23, y: 24 }

ES2017 представил Object.entries, этот метод может преобразовывать объекты в массивы, чтобы объекты могли использовать множество встроенных методов в прототипе массива, таких как map, filter, reduce, например, мы хотим извлечь все значения в следующий объект obj больше 21 пары ключ-значение, как работать?

// ES10之前
const obj = {
  a: 21,
  b: 22,
  c: 23
}
console.log(Object.entries(obj)) // [['a',21],["b", 22],["c", 23]]
let arr = Object.entries(obj).filter(([a, b]) => b > 21) // [["b", 22],["c", 23]]
let obj1 = {}
for (let [name, age] of arr) {
  obj1[name] = age
}
console.log(obj1) // {b: 22, c: 23}

В вышеприведенном примере получается массив arr.Если вы хотите снова преобразовать его в объект, вам нужно вручную написать некоторый код для работы с ним, но с Object.fromEntries() этого легко добиться

// 用Object.fromEntries()来实现
const obj = {
  a: 21,
  b: 22,
  c: 23
}
let res = Object.fromEntries(Object.entries(obj).filter(([a, b]) => b > 21))
console.log(111, res) // {b: 22, c: 23}

Поддержка Object.fromEntries():

4. String.trimStart и String.trimEnd

Удалите ведущие и задние пробелы, прежде чем мы используем регулярные выражения для достижения, теперь ES10 добавил два новых функция, чтобы облегчить!

Метод trimStart() удаляет пробелы в начале строки, trimLeft() — псевдоним для этого метода.

let str = ' 前端工匠 '
console.log(str.length) // 6
str = str.trimStart()
console.log(str.length) // 5
let str1 = str.trim() // 清除前后的空格
console.log(str1.length) // 4
str.replace(/^\s+/g, '') // 也可以用正则实现开头删除空格

Метод trimEnd() удаляет пробелы с правого конца строки, trimRight — это псевдоним для trimEnd.

let str = ' 浪里行舟 '
console.log(str.length) // 6
str = str.trimEnd()
console.log(str.length) // 5
let str1 = str.trim() //清除前后的空格
console.log(str1.length) // 4
str.replace(/\s+$/g, '') // 也可以用正则实现右端移除空白字符

String.trimStart и String.trimEnd имеют одинаковую совместимость.На следующем рисунке в качестве примера используется trimStart:

5.String.prototype.matchAll

Если регулярное выражение имеет несколько совпадений в строке, обычно используйте модификатор g или модификатор y и удаляйте их одно за другим в цикле.

function collectGroup1 (regExp, str) {
  const matches = []
  while (true) {
    const match = regExp.exec(str)
    if (match === null) break
    matches.push(match[1])
  }
  return matches
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// [ 'foo', 'bar', 'baz' ]

Стоит отметить, что без модификатора /g .exec() вернет только первое совпадение. Теперь с помощью метода String.prototype.matchAll ES9 все совпадения могут быть получены одновременно.

function collectGroup1 (regExp, str) {
  let results = []
  for (const match of str.matchAll(regExp)) {
    results.push(match[1])
  }
  return results
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// ["foo", "bar", "baz"]

В приведенном выше коде, поскольку string.matchAll(regex) возвращает обходчик, его можно получить с помощью цикла for...of.

Поддержка String.prototype.matchAll:

6. попробуй… поймай

В ES10 параметр в операторе try-catch стал необязательным. Раньше, когда мы писали оператор catch, нам приходилось передавать параметр исключения. Это означает, что даже если нам вообще не нужно использовать этот параметр исключения в catch, его необходимо передать в

// ES10之前
try {
  // tryCode
} catch (err) {
  // catchCode
}

Здесь err — обязательный параметр, который можно опустить в ES10:

// ES10
try {
  console.log('Foobar')
} catch {
  console.error('Bar')
}

Поддержка try...catch:

7.BigInt

Все числа в JavaScript хранятся как 64-битные числа с плавающей запятой, что накладывает два основных ограничения на представление чисел. Во-первых, точность числовых значений может достигать только 53 двоичных цифр (эквивалентно 16 десятичным цифрам), а целые числа, превышающие этот диапазон, не могут быть точно представлены в JavaScript, что делает JavaScript непригодным для точных расчетов в науке и финансах. Второй — это значение, большее или равное 2 в степени 1024, которое не может быть представлено в JavaScript и возвращает бесконечность.

// 超过 53 个二进制位的数值,无法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
// 超过 2 的 1024 次方的数值,无法表示
Math.pow(2, 1024) // Infinity

Теперь ES10 представляет новый тип данных BigInt (большое целое число) для решения этой проблемы. BigInt используется только для представления целых чисел, количество цифр не ограничено, и целые числа с любым количеством цифр могут быть представлены точно.

Создать значение типа BigInt также просто, как добавить n к числу. Например, 123 становится 123n. Вы также можете использовать глобальный метод BigInt(value) для преобразования, а значение входного параметра представляет собой число или числовую строку.

const aNumber = 111;
const aBigInt = BigInt(aNumber);
aBigInt === 111n // true
typeof aBigInt === 'bigint' // true
typeof 111 // "number"
typeof 111n // "bigint"

Если считать BigInt, количество примитивных типов в JavaScript увеличивается с 6 до 7.

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (new in ECMAScript 2015)
  • BigInt (new in ECMAScript 2019)

Поддержка BigInt:

8.Symbol.prototype.description

Мы знаем, что описание Symbol хранится только во внутреннем [[Description]], недоступном для внешнего мира напрямую, мы можем прочитать это свойство только при вызове toString() Symbol:

Symbol('desc').description;  // "desc"
Symbol('').description;      // ""
Symbol().description;        // undefined

Поддержка Symbol.prototype.description:

9.Function.prototype.toString()

В ES2019 функция Function.toString() изменилась. Когда этот метод выполнялся ранее, результирующая строка не содержала пробелов. И теперь результирующая строка выглядит как оригинальный исходный код:

function sum(a, b) {
  return a + b;
}
console.log(sum.toString());
// function sum(a, b) {
//  return a + b;
// }

Поддержка Function.prototype.toString():

использованная литература