ES означает ECMAScript, ECMAScript — это стандартизированный язык сценариев, разработанный ECMA. Версия ECMAScript, используемая в настоящее время JavaScript,ECMA-417. Последнюю информацию о ECMA можно посмотреть наECMA newsПроверить.
Спецификация ECMA в конечном счетеTC39завершено. TC39 состоит из различных сторон, включая поставщиков браузеров, которые встречаются, чтобы продвигать предложение JavaScript по строгому пути разработки. От предложения до выбора спецификации ECMA есть следующие этапы:
- Этап 0: соломинка — представление исходной идеи.
- Этап 1: предложение. Официальный документ с предложением, поддерживаемый как минимум одним членом TC39 и включающий пример API.
- Этап 2: черновик — первоначальная версия функциональной спецификации, содержащая две экспериментальные реализации функциональной спецификации.
- Этап 3: кандидат — спецификация предложения проходит проверку и получает отзывы от поставщиков.
- Этап 4: завершен. Предложение готово к добавлению в ECMAScript, но может потребоваться больше времени, чтобы добраться до браузера или Nodejs.
Что нового в ES6 (2015)
ES6 имеет больше функций и был стандартизирован почти через 6 лет после выпуска ES5 (с 2009-11 по 2015-6). Между двумя выпусками проходит большой промежуток времени, поэтому в ES6 больше возможностей. Вот несколько часто используемых:
- Добрый
- модульный
- стрелочная функция
- Значение параметра функции по умолчанию
- строка шаблона
- присваивание деструктуризации
- спред оператор
- Сокращение свойства объекта
- Promise
- Пусть и Const
1. Класс (класс)
Разработчики, знакомые с чистыми объектно-ориентированными языками, такими как Java, object-c, c# и т. д., будут иметь особое чувство класса. В ES6 появились классы, чтобы сделать объектно-ориентированное программирование на JavaScript проще и понятнее.
class Animal {
// 构造函数,实例化的时候将会被调用,如果不指定,那么会有一个不带参数的默认构造函数.
constructor(name,color) {
this.name = name;
this.color = color;
}
// toString 是原型对象上的属性
toString() {
console.log('name:' + this.name + ',color:' + this.color);
}
}
var animal = new Animal('dog','white');//实例化Animal
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
class Cat extends Animal {
constructor(action) {
// 子类必须要在constructor中指定super 函数,否则在新建实例的时候会报错.
// 如果没有置顶consructor,默认带super函数的constructor将会被添加、
super('cat','white');
this.action = action;
}
toString() {
console.log(super.toString());
}
}
var cat = new Cat('catch')
cat.toString();
// 实例cat 是 Cat 和 Animal 的实例,和Es5完全一致。
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
2. Модульный (Module)
ES5 не поддерживает нативную модульность, в ES6 модули были добавлены как важная часть. Функция модуля в основном состоит из экспорта и импорта. Каждый модуль имеет свою собственную область видимости.Отношения взаимного вызова между модулями заключаются в указании интерфейса, предоставляемого модулем посредством экспорта, и в обращении к интерфейсу, предоставляемому другими модулями, посредством импорта. Он также создает пространства имен для модулей, чтобы предотвратить конфликты имен для функций.
экспорт (экспорт)
ES6 позволяет использовать экспорт для экспорта нескольких переменных или функций в модуль.
переменная экспорта
//test.js
export var name = 'Rainbow'
Опыт: ES6 поддерживает не только экспорт переменных, но и экспорт констант.
export const sqrt = Math.sqrt;//导出常量
ES6 рассматривает файл как модуль, а указанный выше модуль экспортирует переменную через экспорт. Модуль также может одновременно выводить наружу несколько переменных.
//test.js
var name = 'Rainbow';
var age = '24';
export {name, age};
функция экспорта
// myModule.js
export function myModule(someArg) {
return someArg;
}
импорт (импорт)
После того, как выходные данные модуля определены, на них можно ссылаться посредством импорта в другом модуле.
import {myModule} from 'myModule';// main.js
import {name,age} from 'test';// test.js
Вывод: оператор импорта может одновременно импортировать функции по умолчанию и другие переменные.
import defaultMethod, { otherMethod } from 'xxx.js';
3. Функция стрелки
Это одна из самых захватывающих функций в ES6.=>
Это не просто сокращение для функции ключевого слова, но и другие преимущества. Функция стрелки использует тот же код, что и окружающий код.this
var self = this;
var that = this
=>
// 箭头函数的例子
()=>1
v=>v+1
(a,b)=>a+b
()=>{
alert("foo");
}
e=>{
if (e == 0){
return 0;
}
return 1000/e;
}
неправильный подход
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
}
componentWillUnmount(){
AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
}
onAppPaused(event){
}
}
правильный путь
class PauseMenu extends React.Component{
constructor(props){
super(props);
this._onAppPaused = this.onAppPaused.bind(this);
}
componentWillMount(){
AppStateIOS.addEventListener('change', this._onAppPaused);
}
componentWillUnmount(){
AppStateIOS.removeEventListener('change', this._onAppPaused);
}
onAppPaused(event){
}
}
В дополнение к вышеперечисленным практикам мы также можем сделать это:
class PauseMenu extends React.Component{
componentWillMount(){
AppStateIOS.addEventListener('change', this.onAppPaused);
}
componentWillUnmount(){
AppStateIOS.removeEventListener('change', this.onAppPaused);
}
onAppPaused = (event) => {
//把函数直接作为一个arrow function的属性来定义,初始化的时候就绑定好了this指针
}
}
Следует отметить, что: независимо от того, является ли это функцией привязки или стрелочной функцией, новая ссылка на функцию возвращается каждый раз, когда она выполняется, поэтому, если вам также нужна ссылка на функцию для чего-то еще (например, для удаления слушателя), тогда вы необходимо сохранить эту ссылку самостоятельно.
4.Значение параметра функции по умолчанию
ES6 поддерживает установку значений по умолчанию для функций при их определении:
function foo(height = 50, color = 'red')
{
// ...
}
Не используйте значение по умолчанию:
function foo(height, color)
{
var height = height || 50;
var color = color || 'red';
//...
}
Обычно это нормально писать, но когда参数的布尔值为false
, будут проблемы. Например, мы вызываем функцию foo следующим образом:
foo(0, "")
потому что0的布尔值为false
, поэтому значение высоты будет равно 50. Точно так же значение цвета — «красный».
так,函数参数默认值
Код может не только стать более лаконичным, но и избежать некоторых проблем.
5. Строки шаблона
Поддержка ES6模板字符串
, что делает объединение строк более лаконичным и интуитивно понятным.
Без использования строк шаблона:
var name = 'Your name is ' + first + ' ' + last + '.'
Используйте строки шаблона:
var name = `Your name is ${first} ${last}.`
Пройдено в ES6${}
Вы можете выполнить конкатенацию строк, просто заключив переменные в фигурные скобки.
6.присваивание деструктуризации
Синтаксис присваивания деструктурирования — это выражение в JavaScript, которое может легко извлекать значения из массивов или объектов и присваивать их определенным переменным.
получить значение в массиве
Получить значения из массива и присвоить их переменным, порядок переменных соответствует порядку объектов в массиве.
var foo = ["one", "two", "three", "four"];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
//如果你要忽略某些值,你可以按照下面的写法获取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"
//你也可以这样写
var a, b; //先声明变量
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
Если из массива не получено никакого значения, вы можете установить значение по умолчанию для переменной.
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
Деструктурирующее присваивание может легко поменять местами значения двух переменных.
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
получить значение в объекте
const student = {
name:'Ming',
age:'18',
city:'Shanghai'
};
const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"
7. Оператор спреда
延展操作符...
Выражения массива или строки могут быть расширены синтаксически во время вызова функции/построения массива; выражения объекта также могут быть расширены по ключу-значению при создании объектов.
грамматика
вызов функции:
myFunction(...iterableObj);
Конструкция массива или строка:
[...iterableObj, '4', ...'hello', 6];
При создании объекта клонируйте или копируйте свойства (новые функции в спецификации ECMAScript 2018):
let objClone = { ...obj };
Сценарии применения
Использовать оператор распространения в вызове функции
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
//不使用延展操作符
console.log(sum.apply(null, numbers));
//使用延展操作符
console.log(sum(...numbers));// 6
построить массив
При отсутствии синтаксиса расширения такие методы, как push, splice и concat, можно комбинировать только для превращения существующих элементов массива в часть нового массива. Синтаксис unwind позволяет создавать новые массивы проще и элегантнее:
const stuendts = ['Jine','Tom'];
const persons = ['Tony',... stuendts,'Aaron','Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]
Подобно расширению списка параметров,...
При построении массива слов его можно использовать много раз в любой позиции.
Копия массива
var arr = [1, 2, 3];
var arr2 = [...arr]; // 等同于 arr.slice()
arr2.push(4);
console.log(arr2)//[1, 2, 3, 4]
Синтаксис расширения согласуется с поведением Object.assign(), который выполняет поверхностное копирование (проходит только один уровень).
объединить несколько массивов
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 将 arr2 中所有元素附加到 arr1 后面并返回
//等同于
var arr4 = arr1.concat(arr2);
Оператор Spread добавляет поддержку объектов в ECMAScript 2018
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象: { foo: "baz", x: 42, y: 13 }
Приложение в Реакции
Обычно, когда мы инкапсулируем компонент, мы предоставляем некоторые свойства для реализации функций. Передайте реквизиты, которые в большинстве случаев должны быть явными для внешнего использования. Но при передаче большого количества реквизита это будет очень громоздко, тогда можно использовать...(延展操作符,用于取出参数对象的所有可遍历属性)
передавать.
В нормальных условиях мы должны написать
<CustomComponent name ='Jine' age ={21} />
Используйте ... , эквивалентный приведенному выше
const params = {
name: 'Jine',
age: 21
}
<CustomComponent {...params} />
Сотрудничайте с назначением деструктурирования, чтобы избежать передачи некоторых ненужных параметров.
var params = {
name: '123',
title: '456',
type: 'aaa'
}
var { type, ...other } = params;
<CustomComponent type='normal' number={2} {...other} />
//等同于
<CustomComponent type='normal' number={2} name='123' title='456' />
8. Сокращение свойства объекта
ES6 позволяет нам устанавливать свойства объекта без указания имени свойства.
Не использую ES6
const name='Ming',age='18',city='Shanghai';
const student = {
name:name,
age:age,
city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
Объекты должны содержать свойства и значения, что очень избыточно.
Используйте ES6
const name='Ming',age='18',city='Shanghai';
const student = {
name,
age,
city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}
Записывайте переменные прямо в объект, что очень лаконично.
9.Promise
Промисы — это решение для асинхронного программирования, более элегантное, чем традиционный обратный вызов решения. Впервые он был предложен и реализован сообществом, ES6 вписал его в стандарт языка, унифицированное использование и изначально предоставил объекты Promise.
Не использую ES6
Вложите две функции обратного вызова setTimeout:
setTimeout(function()
{
console.log('Hello'); // 1秒后输出"Hello"
setTimeout(function()
{
console.log('Hi'); // 2秒后输出"Hi"
}, 1000);
}, 1000);
Используйте ES6
var waitSecond = new Promise(function(resolve, reject)
{
setTimeout(resolve, 1000);
});
waitSecond
.then(function()
{
console.log("Hello"); // 1秒后输出"Hello"
return waitSecond;
})
.then(function()
{
console.log("Hi"); // 2秒后输出"Hi"
});
Приведенный выше код использует два then для сериализации асинхронного программирования, избегая ада обратных вызовов:
10. Поддержка let и const
В прошлом в JS не было области видимости на уровне блоков. Const и let заполнили этот удобный пробел. И const, и let являются областью действия на уровне блоков.
Переменные, определенные с помощью var, относятся к области действия функции:
{
var a = 10;
}
console.log(a); // 输出10
Переменные, определенные с помощью let и const, имеют блочную область видимости:
{
let a = 10;
}
console.log(a); //-1 or Error“ReferenceError: a is not defined”
Что нового в ES7 (2016)
ES2016 добавил две небольшие функции для иллюстрации процесса нормализации:
- Метод array include() используется для определения того, содержит ли массив указанное значение.В зависимости от ситуации, если он содержит, он возвращает true, иначе возвращает false.
- Оператор индекса A**b, аналогичный Math.Pow(A,B).
1.Array.prototype.includes()
includes()
Функция используется для определения того, содержит ли массив указанное значение, и возвращает значение, если содержитtrue
, иначе возвратfalse
.
includes
функция сindexOf
Функции очень похожи, следующие два выражения эквивалентны:
arr.includes(x)
arr.indexOf(x) >= 0
Далее определим, содержит ли число элемент:
Потренируйтесь перед ES7
использоватьindexOf()
Чтобы проверить, существует ли элемент в массиве, вам нужно определить, равно ли возвращаемое значение -1:
let arr = ['react', 'angular', 'vue'];
if (arr.indexOf('react') !== -1)
{
console.log('react存在');
}
Используйте ES7 include()
Используйте include(), чтобы проверить, существует ли элемент в массиве, что более интуитивно понятно и просто:
let arr = ['react', 'angular', 'vue'];
if (arr.includes('react'))
{
console.log('react存在');
}
2. Экспоненциальный оператор
Оператор экспоненты был введен в ES7.**
,**
С участиемMath.pow(..)
Эквивалентный результат расчета.
Не используйте оператор экспоненты
Используйте пользовательскую рекурсивную функцию calculateExponent или Math.pow() для выполнения экспоненциальных операций:
function calculateExponent(base, exponent)
{
if (exponent === 1)
{
return base;
}
else
{
return base * calculateExponent(base, exponent - 1);
}
}
console.log(calculateExponent(2, 10)); // 输出1024
console.log(Math.pow(2, 10)); // 输出1024
Используйте экспоненциальный оператор
Используйте оператор экспоненты **, точно так же, как операторы +, - и т. д.:
console.log(2**10);// 输出1024
Что нового в ES8 (2017)
- async/await
Object.values()
Object.entries()
- String padding:
padStart()
а такжеpadEnd()
, строка заполнения достигает текущей длины - Разрешить запятые в конце списков параметров функций
Object.getOwnPropertyDescriptors()
-
ShareArrayBuffer
а такжеAtomics
Объект для чтения и записи из разделяемых областей памяти
1.async/await
ES2018 представляет асинхронные итераторы, которые аналогичны обычным итераторам, за исключениемnext()
Метод возвращает обещание. следовательноawait
может иfor...of
Циклы используются вместе для последовательного выполнения асинхронных операций. Например:
async function process(array) {
for await (let i of array) {
doSomething(i);
}
}
2.Object.values()
Object.values()
этоObject.keys()
Аналогичная новая функция, но возвращает все значения собственных свойств Объекта, исключая унаследованные значения.
Предположим, мы хотим перебрать следующие объектыobj
Все значения:
const obj = {a: 1, b: 2, c: 3};
Не использовать Object.values(): ES7
const vals=Object.keys(obj).map(key=>obj[key]);
console.log(vals);//[1, 2, 3]
Использование Object.values(): ES8
const values=Object.values(obj1);
console.log(values);//[1, 2, 3]
Как видно из кода вышеObject.values()
Это избавляет нас от необходимости обхода ключей и получения значений в соответствии с этими ключами.
3.Object.entries()
Object.entries()
Функция возвращает массив пар ключ-значение для собственных перечисляемых свойств данного объекта.
Далее, давайте пройдемся по вышеизложенномуobj
Ключ и значение всех свойств объекта:
Не использовать Object.entries(): ES7
Object.keys(obj).forEach(key=>{
console.log('key:'+key+' value:'+obj[key]);
})
//key:a value:1
//key:b value:2
//key:c value:3
Использование Object.entries(): ES8
for(let [key,value] of Object.entries(obj1)){
console.log(`key: ${key} value:${value}`)
}
//key:a value:1
//key:b value:2
//key:c value:3
4.String padding
В String в ES8 добавлены две новые функции экземпляра.String.prototype.padStart
а такжеString.prototype.padEnd
, позволяя добавлять пустые строки или другие строки в начало или конец исходной строки.
String.padStart(targetLength,[padString])
- targetLength: целевая длина, до которой необходимо дополнить текущую строку. Если это значение меньше длины текущей строки, возвращается сама текущая строка.
- padString: (необязательно) строка заполнения. Если строка слишком длинная и длина дополненной строки превышает целевую длину, будет сохранена только самая левая часть, а остальные части будут усечены.Значение этого параметра по умолчанию — " ".
console.log('0.0'.padStart(4,'10')) //10.0
console.log('0.0'.padStart(20))// 0.00
String.padEnd(targetLength,padString])
- targetLength: целевая длина, до которой необходимо дополнить текущую строку. Если это значение меньше длины текущей строки, возвращается сама текущая строка.
- padString: (необязательно) строка заполнения. Если строка слишком длинная и длина дополненной строки превышает целевую длину, будет сохранена только самая левая часть, а остальные части будут усечены.Значение этого параметра по умолчанию — " ";
console.log('0.0'.padEnd(4,'0')) //0.00
console.log('0.0'.padEnd(10,'0'))//0.00000000
5. Разрешить запятые в конце списков параметров функций
Основная функция состоит в том, чтобы облегчить использование git для совместной разработки несколькими людьми, чтобы изменить одну и ту же функцию, чтобы уменьшить ненужные изменения строк.
6.Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors()
Функция используется для получения дескрипторов всех собственных свойств объекта, если собственных свойств нет, возвращает пустой объект.
Прототип функции:
Object.getOwnPropertyDescriptors(obj)
вернутьobj
Дескрипторы всех собственных свойств объекта или пустой объект, если собственных свойств нет.
const obj2 = {
name: 'Jine',
get age() { return '18' }
};
Object.getOwnPropertyDescriptors(obj2)
// {
// age: {
// configurable: true,
// enumerable: true,
// get: function age(){}, //the getter function
// set: undefined
// },
// name: {
// configurable: true,
// enumerable: true,
// value:"Jine",
// writable:true
// }
// }
7. Объект SharedArrayBuffer
Объекты SharedArrayBuffer используются для представления универсального буфера фиксированной длины необработанных двоичных данных.Подобно объектам ArrayBuffer, они оба могут использоваться для создания представлений в общей памяти. В отличие от ArrayBuffer, SharedArrayBuffer нельзя отсоединить.
/**
*
* @param {*} length 所创建的数组缓冲区的大小,以字节(byte)为单位。
* @returns {SharedArrayBuffer} 一个大小指定的新 SharedArrayBuffer 对象。其内容被初始化为 0。
*/
new SharedArrayBuffer(length)
8.Атомные объекты
Объект Atomics предоставляет набор статических методов для выполнения атомарных операций над объектами SharedArrayBuffer.
Эти атомарные операции относятся к модулю Atomics. В отличие от обычных глобальных объектов, Atomics не являются конструкторами, поэтому их нельзя вызывать с помощью оператора new, а также нельзя вызывать напрямую как функцию. Все свойства и методы Atomics являются статическими (как объекты Math).
Несколько потоков, совместно использующих память, могут читать и записывать данные в одно и то же место в одно и то же время. Атомарные операции гарантируют, что значение считываемых или записываемых данных соответствует ожидаемому, то есть следующая атомарная операция не начнется до тех пор, пока не завершится предыдущая атомарная операция, и процесс операции не будет прерван.
- Atomics.add()
Добавляет элемент массива в указанной позиции к заданному значению и возвращает значение элемента перед добавлением.
- Atomics.and()
Добавляет элемент массива в указанной позиции с заданным значением и возвращает значение элемента перед операцией И.
- Atomics.compareExchange()
Если указанный элемент в массиве равен заданному значению, обновите его новым значением и верните предыдущее значение элемента.
- Atomics.exchange()
Обновляет указанный элемент в массиве до заданного значения и возвращает значение до обновления элемента.
- Atomics.load()
Возвращает значение указанного элемента в массиве.
- Atomics.or()
Или элемент массива в указанной позиции с заданным значением и вернуть значение элемента перед операцией ИЛИ.
- Atomics.store()
Присваивает указанному элементу массива заданное значение и возвращает это значение.
- Atomics.sub()
Вычитает элемент массива в указанной позиции из заданного значения и возвращает значение элемента перед вычитанием.
- Atomics.xor()
Исключает элемент массива в указанной позиции с заданным значением и возвращает значение элемента до операции XOR.
Методы wait() и wake() используют модель фьютексов в Linux (быстрый мьютекс пользовательского пространства, быстрый мьютекс пользовательского пространства), которая может заставить процесс ждать, пока определенное условие не станет истинным, в основном используется для достижения блокировки.
- Atomics.wait()
检测数组中某个指定位置上的值是否仍然是给定值,是则保持挂起直到被唤醒或超时。 Возвращаемое значение: "ok", "not-equal" или "time-out". При вызове будет сгенерировано исключение, если текущий поток не разрешает блокировку (большинство браузеров не позволяют вызывать wait() в основном потоке).
- Atomics.wake()
Пробуждает поток, ожидающий элемента в указанной позиции в массиве в очереди ожидания. Возвращаемое значение — количество успешно пробужденных потоков.
- Atomics.isLockFree(size)
Может использоваться для определения того, поддерживает ли текущая система атомарные операции на аппаратном уровне. Для массива указанного размера, если текущая система поддерживает атомарные операции на аппаратном уровне, возвращается true; в противном случае это означает, что для массива каждая атомарная операция в объекте Atomics может быть реализована только с использованием блокировок. Эта функция предназначена для технических специалистов. -->
Что нового в ES9 (2018)
- Асинхронная итерация
- Promise.finally()
- Свойства отдыха/спреда
- Именованные группы захвата регулярного выражения(Регулярное выражение названных групп захвата)
- Обратное утверждение регулярного выражения(смотреть за)
- Шаблон регулярного выражения dotAll
- Регулярные выражения Unicode Escape
- Строки-шаблоны без управляющих последовательностей
1. Асинхронная итерация
существуетasync/await
В какой-то момент вы можете попытаться вызвать асинхронную функцию в синхронном цикле. Например:
async function process(array) {
for (let i of array) {
await doSomething(i);
}
}
Этот код не будет работать, как и следующий:
async function process(array) {
array.forEach(async i => {
await doSomething(i);
});
}
В этом коде сам цикл остается синхронным и завершается до всех вызовов внутренней асинхронной функции.
ES2018 представляет асинхронные итераторы, которые аналогичны обычным итераторам, за исключениемnext()
Метод возвращает обещание. следовательноawait
может иfor...of
Циклы используются вместе для последовательного выполнения асинхронных операций. Например:
async function process(array) {
for await (let i of array) {
doSomething(i);
}
}
2.Promise.finally()
Цепочка вызовов обещания либо успешно достигла последнего.then()
, или не срабатывает.catch()
. В некоторых случаях вы хотите запускать один и тот же код вне зависимости от того, успешно ли выполнено обещание или нет, например, очистка, удаление диалогового окна, закрытие соединения с базой данных и т. д.
.finally()
Позволяет указать конечную логику:
function doSomething() {
doSomething1()
.then(doSomething2)
.then(doSomething3)
.catch(err => {
console.log(err);
})
.finally(() => {
// finish here!
});
}
3. Свойство Rest/Spread
Представлен ES2015Параметр покояа такжеспред оператор. Три точки (...) предназначены только для массивов. Синтаксис остальных параметров позволяет нам представлять неопределенное количество параметров в виде массива.
restParam(1, 2, 3, 4, 5);
function restParam(p1, p2, ...p3) {
// p1 = 1
// p2 = 2
// p3 = [3, 4, 5]
}
Оператор спреда работает наоборот, превращая массив в один параметр, который можно передать функции. НапримерMath.max()
Возвращает наибольшее из заданных чисел:
const values = [99, 100, -1, 48, 16];
console.log( Math.max(...values) ); // 100
ES2018 предоставляет те же параметры Rest () и оператор распространения, что и массивы для деструктуризации объектов, простой пример:
const myObject = {
a: 1,
b: 2,
c: 3
};
const { a, ...x } = myObject;
// a = 1
// x = { b: 2, c: 3 }
Или вы можете использовать его для передачи аргументов функциям:
restParam({
a: 1,
b: 2,
c: 3
});
function restParam({ a, ...x }) {
// a = 1
// x = { b: 2, c: 3 }
}
Как и массивы, параметры Rest можно использовать только в конце объявления. Кроме того, он работает только на верхнем уровне каждого объекта, а не в том случае, если объекты вложены в объекты.
Расширенные операторы можно использовать внутри других объектов, например:
const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = { ...obj1, z: 26 };
// obj2 is { a: 1, b: 2, c: 3, z: 26 }
Объект можно скопировать с помощью оператора распространения, напримерobj2 = {...obj1}
,ноЭто просто мелкая копия объекта. Кроме того, если атрибут объекта A является объектом B, то в клонированном объекте cloneB атрибут указывает на объект B.
4. Именованные группы захвата с помощью регулярных выражений
Регулярные выражения JavaScript могут возвращать совпадающий объект — массив, содержащий совпадающие строки, например:YYYY-MM-DD
Формат парсинга дат:
const
reDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match[1], // 2018
month = match[2], // 04
day = match[3]; // 30
Такой код трудно читать, а изменение структуры регулярного выражения может привести к изменению индекса соответствующего объекта.
ES2018 позволяет именованным группам захвата использовать символы?<name>
, в скобе захвата проема(
Сразу после названия пример следующий:
const
reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match.groups.year, // 2018
month = match.groups.month, // 04
day = match.groups.day; // 30
Любые именованные группы, которые не совпадают, будут возвращеныundefined
.
Именованные захваты также могут использоваться вreplace()
метод. Например, чтобы преобразовать дату в формат США ММ-ДД-ГГГГ:
const
reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
d = '2018-04-30',
usDate = d.replace(reDate, '$<month>-$<day>-$<year>');
5. Обратное утверждение регулярного выражения
В настоящее время JavaScript поддерживает просмотр вперед в регулярных выражениях. Это означает, что совпадение происходит, но захвата не происходит, и утверждение не включается во все поле совпадения. Например, чтобы получить символ валюты из цены:
const
reLookahead = /\D(?=\d+)/,
match = reLookahead.exec('$123.89');
console.log( match[0] ); // $
Введенный ES2018 работает так же, но соответствует предыдущему ретроспективному анализу, так что я могу игнорировать символ валюты и просто фиксировать номер цены:
const
reLookbehind = /(?<=\D)\d+/,
match = reLookbehind.exec('$123.89');
console.log( match[0] ); // 123.89
Вышеположительное отрицательное утверждение, а не число\D
должен существовать. Так же естьОтрицательное обратное утверждение, указывающее, что значение не должно существовать, например:
const
reLookbehindNeg = /(?<!\D)\d+/,
match = reLookbehind.exec('$123.89');
console.log( match[0] ); // null
6. Шаблон регулярного выражения dotAll
средняя точка регулярного выражения.
соответствует любому одиночному символу, кроме возврата каретки, токенаs
Измените это поведение, чтобы разрешить разделители строк, например:
/hello.world/.test('hello\nworld'); // false
/hello.world/s.test('hello\nworld'); // true
7. Регулярные выражения Unicode Escape
До сих пор собственный доступ к свойствам символов Unicode в регулярных выражениях не разрешался. ES2018 добавил экранирование свойств Unicode - формы\p{...}
а также\P{...}
, используя токен в регулярном выраженииu
(Юникод), в\p
Внутри блока вы можете установить атрибуты, которые должны сопоставляться, вместо определенного контента в виде пар ключ-значение. Например:
const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test('π'); // true
Эта функция позволяет избежать использования определенных диапазонов Unicode для суждения о типе контента, улучшая удобочитаемость и удобство сопровождения.
8. Строки-шаблоны без управляющих последовательностей
До,\u
запускает экранирование юникода,\x
начинает шестигранный побег,\
за которым следует цифра, чтобы начать восьмеричное escape-последовательность. Это делает невозможным создание определенных строк, таких как пути к файлам Windows.C:\uuu\xxx\111
. Более подробная информациястрока шаблона.
Что нового в ES10 (2019)
- Символы разделителя строк (U+2028) и разделителя сегментов (U+2029) теперь разрешены в строковых литералах, соответствующих JSON.
- Дружелюбный json.stringify.
- Добавлен массив
flat()
Методы иflatMap()
метод - Добавлены строки
trimStart()
Методы иtrimEnd()
метод Object.fromEntries()
Symbol.prototype.description
String.prototype.matchAll
-
Function.prototype.toString()
Теперь возвращает точные символы, включая пробелы и комментарии - упрощать
try {} catch {}
,Исправлятьcatch
связывать - новый базовый тип данных
BigInt
- globalThis
- import()
- Legacy RegEx
- Методы и средства доступа частного экземпляра
1. Символы разделителя строк (U+2028) и разделителя сегментов (U+2029) теперь разрешены в строковых литералах, соответствующих JSON.
Ранее эти символы обрабатывались как символы конца строки в строковых литералах, поэтому их использование приводило к исключению SyntaxError.
2. Более удобный JSON.stringify
Если входные данные представлены в формате Unicode, но за пределами допустимого диапазона символов, JSON.stringify ранее возвращал искаженную строку Unicode. Теперь реализует изменение JSON.stringify.Предложение этапа 3, поэтому он выводит escape-последовательности для него, что делает его допустимым Unicode (и представленным в UTF-8)
3. Добавлен массивflat()
Методы иflatMap()
метод
flat()
а такжеflatMap()
По сути, это операции сокращения и объединения.
Array.prototype.flat()
flat()
Метод рекурсивно проходит массив до указанной глубины и возвращает все элементы, объединенные с элементами в пройденных подмассивах, в новый массив.
-
flat()
Самая основная функция метода — уменьшить размерность массива
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
//使用 Infinity 作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity);
// [1, 2, 3, 4, 5, 6]
- Во-вторых, вы также можете использовать
flat()
Особенность метода удаления пустых элементов массива
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]
Array.prototype.flatMap()
flatMap()
Метод сначала сопоставляет каждый элемент с помощью функции сопоставления, а затем сжимает результат в новый массив. Это почти то же самое, что map и flat со значением глубины 1, но flatMap обычно немного более эффективен при объединении в один метод.
Здесь мы сравниваем метод map с методом flatMap.
var arr1 = [1, 2, 3, 4];
arr1.map(x => [x * 2]);
// [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]
// 只会将 flatMap 中的函数返回的数组 “压平” 一层
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]
4. Добавлена строкаtrimStart()
Методы иtrimEnd()
метод
Эти два новых метода просты для понимания, они удаляют пробельные символы в начале и в конце строки соответственно, их здесь объявлять не нужно.
5.Object.fromEntries()
Object.entries()
Функция метода состоит в том, чтобы вернуть массив пар ключ-значение собственных перечислимых свойств данного объекта в том же порядке, что и при использовании цикла for...in для обхода объекта (разница в том, что for-in loop также перечисляет свойства цепочки прототипов в ).
а такжеObject.fromEntries()
являетсяObject.entries()
Инверсия.
Object.fromEntries()
Функция передается в виде списка пар ключ-значение и возвращает новый объект с этими парами ключ-значение. Параметр итерации должен быть объектом, реализующим метод @iterator, возвращающим объект итератора. Он создает массивоподобный объект с двумя элементами, первый элемент — это значение, которое будет использоваться в качестве ключа свойства, а второй элемент — это значение, связанное с этим ключом свойства.
- С помощью Object.fromEntries Map можно преобразовать в Object:
const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
- С помощью Object.fromEntries вы можете преобразовать массив в объект:
const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ];
const obj = Object.fromEntries(arr);
console.log(obj); // { 0: "a", 1: "b", 2: "c" }
6.Symbol.prototype.description
При создании символа с помощью фабричной функции Symbol() вы можете дополнительно указать строку в качестве описания через параметр:
const sym = Symbol('The description');
Раньше единственным способом доступа к описанию было преобразование символа в строку:
assert.equal(String(sym), 'Symbol(The description)');
Геттер Symbol.prototype.description теперь представлен для прямого доступа к описанию:
assert.equal(sym.description, 'The description');
7.String.prototype.matchAll
matchAll()
Метод Возвращает итератор, содержащий все совпадающие регулярные выражения и результаты перехвата пакетов.
Прежде чем появится Matchall, вся информация о совпадениях получается путем вызова regexp.exec в цикле (regexp должен использовать знак /g:
const regexp = RegExp('foo*','g');
const str = 'table football, foosball';
while ((matches = regexp.exec(str)) !== null) {
console.log(`Found ${matches[0]}. Next starts at ${regexp.lastIndex}.`);
// expected output: "Found foo. Next starts at 9."
// expected output: "Found foo. Next starts at 19."
}
Если вы используете matchAll, вам не нужно использовать цикл while плюс метод exec (и регулярное выражение должно использовать флаг /g). Использование matchAll позволит получить возвращаемое значение итератора, что может быть удобнее реализовать с помощью for...of, массива распространения или Array.from():
const regexp = RegExp('foo*','g');
const str = 'table football, foosball';
let matches = str.matchAll(regexp);
for (const match of matches) {
console.log(match);
}
// Array [ "foo" ]
// Array [ "foo" ]
// matches iterator is exhausted after the for..of iteration
// Call matchAll again to create a new iterator
matches = str.matchAll(regexp);
Array.from(matches, m => m[0]);
// Array [ "foo", "foo" ]
matchAll лучше использовать для группировки
var regexp = /t(e)(st(\d?))/g;
var str = 'test1test2';
str.match(regexp);
// Array ['test1', 'test2']
let array = [...str.matchAll(regexp)];
array[0];
// ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1];
// ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]
8.Function.prototype.toString()
Теперь возвращает точные символы, включая пробелы и комментарии.
function /* comment */ foo /* another comment */() {}
// 之前不会打印注释部分
console.log(foo.toString()); // function foo(){}
// ES2019 会把注释一同打印
console.log(foo.toString()); // function /* comment */ foo /* another comment */ (){}
// 箭头函数
const bar /* comment */ = /* another comment */ () => {};
console.log(bar.toString()); // () => {}
9. Модификацияcatch
связывать
До ES10 нам приходилось синтаксически связывать переменные исключения для предложений catch, независимо от того, было это необходимо или нет. Часто блоки catch являются избыточными. Предложение ES10 позволяет нам просто опускать переменные.
Не большое изменение.
было
try {} catch(e) {}
сейчас
try {} catch {}
10. Новые базовые типы данныхBigInt
Теперь существует более 5 базовых типов данных (типов значений) (шесть после ES6)! Плюс BigInt, всего семь основных типов данных, а именно: String, Number, Boolean, Null, Undefined, Symbol, BigInt