Рубрики
Без рубрики

ES5 до ESNext – вот каждая функция добавлена в JavaScript с 2015 года

Я написал эту статью, чтобы помочь вам перейти от предварительно ES6 знаний о JavaScript и быстро добраться до скорости с самыми последними достижениями языка. JavaScript сегодня находится в привилегированном положении, чтобы быть единственным языком, который может работать в браузере, и является высоко

Автор оригинала: FreeCodeCamp Community Member.

Я написал эту статью, чтобы помочь вам перейти от предварительно ES6 знаний о JavaScript и быстро добраться до скорости с самыми последними достижениями языка.

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

Будущее JavaScript собирается быть блестящим. Поддерживая изменениями не должно быть сложнее, чем она уже есть, а моя цель здесь – дать вам быстрый, но всесторонний обзор новых, доступных нам.

Нажмите здесь, чтобы получить PDF/EPUB/MOBI версию этого поста для чтения в автономном режиме

Всякий раз, когда вы читаете о JavaScript, вы неизбежно сможете увидеть один из настоящих Условий: ES3, ES5, ES6, ES7, ES8, ES2015, ES616, ES2017, ECMAScript 2017, ECMAScript 2016, Ecmascript 2015 … Что они имеют в виду?

Все они относятся к Стандарт , называется Ecmascript.

Ecmascript – это Стандарт, на который основан JavaScript , и это часто сокращено Es Отказ

Рядом с JavaScript, другие языки реализуют ECMAScript (ED), в том числе:

  • ActionScript (Язык сценариев вспышки), который теряет популярность, так как Flash будет официально прекращена в 2020 году
  • Jscript (Сценарный диалект Microsoft), поскольку в то время JavaScript поддерживается только Netscape, и войны браузера были на их пике, Microsoft пришлось создать свою собственную версию для Internet Explorer

Но конечно JavaScript это Самый популярный и широко используемая реализация ES.

Почему это странное имя? Ecma International Является ли ассоциация швейцарских стандартов, отвечающих за определение международных стандартов.

Когда был создан JavaScript, он был представлен Netscape и Sun Microsystems в ECMA, и они дали ему имя ecma-262 псевдоним Ecmascript Отказ

Этот пресс-релиз на Netscape и Sun Microsystems (Создатель Java) может помочь выяснить выбор названия, который может включать в себя проблемы с правовым и брендом Microsoft, который был в Комитете, По словам Википедии Отказ

После IE9 Microsoft перестала брендировать свою поддержку ES в браузерах как jscript и запустила его JavaScript (по крайней мере, я не мог найти ссылки на него больше).

По состоянию на 2012 год единственным популярным языком, поддерживающим SECScript SEP, является JavaScript.

Текущая версия Ecmascript

Текущая версия Ecmascript – ES2018 Отказ

Он был выпущен в июне 2018 года.

Что такое TC39.

TC39 – Комитет, который развивается JavaScript.

Члены TC39 являются компаниями, участвующими в производителях JavaScript и браузера, включая Mozilla, Google, Facebook, Apple, Microsoft, Intel, PayPal, Salesforce и другие.

Каждая стандартная версия предложения должна проходить через различные этапы, которые объясняются здесь Отказ

Es versions.

Я обнаружил, почему иногда ES-версия ссылается на версию ES, а иногда и к году, и я запутался в год случайным, будучи -1 на номер, который добавляет к общему путанице вокруг JS/ES?

До ES2015, технические характеристики ECMASSCRICT обычно назывались их изданием. Таким образом, ES5 является официальным названием для обновления спецификации Ecmascript, опубликованного в 2009 году.

Почему это происходит? Во время процесса, который привел к ES2015, название было изменено с ES6 до ES2015, но поскольку это было сделано поздно, люди все еще ссылаются на него как ES6, и сообщество не покинуло издание, называемую позади – Мир все еще зовет ES Releasz по номеру издания Отказ

Эта таблица должна немного очистить вещи:

Давайте погрузимся в конкретные функции, добавленные в JavaScript с ES5. Начнем с функций ES2015.

Пусть и const.

До es2015, var Была единственная конструкция, доступная для определения переменных.

var a = 0

Если вы забудете добавить var Вы будете присвоить значение неразделенной переменной, и результаты могут варьироваться.

В современных средах с включенным строгим режимом вы получите ошибку. В более старых средах (или со строгим режимом отключен) Это будет инициализировать переменную и назначить ее глобальному объекту.

Если вы не инициализируете переменную, когда вы объявляете его, у него будут undefined Значение, пока не назначьте его значение.

var a //typeof a === 'undefined'

Вы можете много раз редить переменную переменю, переопределяя его:

var a = 1
var a = 2

Вы также можете объявить несколько переменных одновременно в том же утверждении:

var a = 1, b = 2

Область это часть кода, в которой отображается переменная.

Переменная инициализирована var За пределами любой функции назначается глобальному объекту, имеет глобальную область и видно везде. Переменная инициализирована var Внутри функции назначаются этой функции, это локально и видно только внутри нее, как и функциональный параметр.

Любая переменная, определенная в функции с тем же именем, что и глобальная переменная, имеет приоритет над глобальной переменной, затенение ее.

Важно понимать, что блок (идентифицированный парой кудрявых скобок) не определяет новый объем. Новый объем создан только при создании функции, потому что var Не имеет возможности блока, но функция.

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

Использование

Пусть Это новая функция, представленная в ES2015, и это, по сути, является блок, находящимся на уровне var Отказ Его объем ограничен блоком, выпиской или выражением, где он определяется, и все содержащиеся внутренние блоки.

Современные разработчики JavaScript могут выбрать только для использования только Пусть и полностью отказаться от использования var Отказ

Определение Пусть За пределами любой функции – вопреки var – Не создает глобальную переменную.

Использование Const.

Переменные объявлены с var или Пусть Можно изменить позже в программе и переназначен. Однажды А Const Инициализируется, его значение никогда не может быть изменено снова, и его нельзя переназначить другое значение.

const a = 'test'

Мы не можем назначить другой буквальный для А const. Однако мы можем мутировать А Если это объект, который предоставляет методы, которые мутируют его содержимое.

Const Не обеспечивает неизменность, просто гарантирует, что ссылка не может быть изменена.

Const имеет блок сферы, такой же, как Пусть Отказ

Современные разработчики JavaScript могут всегда использовать Const Для переменных, которые не нужно переназначить позже в программе, потому что мы всегда должны использовать простейшую конструкцию, доступную, чтобы избежать ошибок по дороге.

Функции стрелки

Функции стрелки, поскольку их введение, навсегда изменилось, как выглядит код JavaScript (и работает).

На мой взгляд, это изменение было так добро пожаловать, что вы сейчас редко видите использование Функция Ключевое слово в современных кодовых базах. Хотя это все еще его использование.

Визуально это простое и приветственное изменение, которое позволяет писать функции с более коротким синтаксисом, от:

const myFunction = function() {
  //...
}

к

const myFunction = () => {
  //...
}

Если функциональный корпус содержит всего одно утверждение, вы можете пропустить кронштейны и писать все на одну строку:

const myFunction = () => doSomething()

Параметры передаются в скобках:

const myFunction = (param1, param2) => doSomething(param1, param2)

Если у вас есть один (и только один) параметр, вы могли бы полностью опустить скобки:

const myFunction = param => doSomething(param)

Благодаря этому короткому синтаксису, функции стрелки поощрять использование небольших функций Отказ

Неявное возвращение

Функции со стрелками позволяют вам иметь неявное возвращение: значения возвращаются без необходимости использовать Возвращение ключевое слово.

Работает в том случае, когда в теле функции есть однострочное заявление:

const myFunction = () => 'test'

myFunction() //'test'

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

const myFunction = () => ({ value: 'test' })

myFunction() //{value: 'test'}

Как это работает в функциях стрелки

это Это концепция, которая может быть сложной, чтобы понять, поскольку она много варьируется в зависимости от контекста, а также варьируется в зависимости от режима JavaScript ( строгий режим или нет).

Важно прояснить эту концепцию, потому что функции стрелки ведут себя очень по-разному по сравнению с регулярными функциями.

При определении как метод объекта, в обычной функции это Относится к объекту, так что вы можете сделать:

const car = {
  model: 'Fiesta',
  manufacturer: 'Ford',
  fullName: function() {
    return `${this.manufacturer} ${this.model}`
  }
}

Призыв Car.fullname () вернется "Ford Fiesta" Отказ

это Область применения со стрелками работает Унаследовано из контекста выполнения. Функция стрелки не связывается это Вообще, поэтому его значение будет выглядеть в стеке вызовов, поэтому в этом коде Car.fullname () не будет работать и вернется строку «Неопределенный неопределенный» :

const car = {
  model: 'Fiesta',
  manufacturer: 'Ford',
  fullName: () => {
    return `${this.manufacturer} ${this.model}`
  }
}

Благодаря этому, функции стрелки не подходят как методы объекта.

Функции стрелки не могут быть использованы в качестве конструкторов, когда создает объект объекта, поднимет Типеррор Отказ

Именно здесь следует использовать регулярные функции, Когда динамический контекст не нужен Отказ

Это также проблема при обработке событий. DOM события слушатели набор это быть целевым элементом, и если вы полагаетесь на это В обработчике события необходима регулярная функция:

const link = document.querySelector('#link')
link.addEventListener('click', () => {
  // this === window
})

const link = document.querySelector('#link')
link.addEventListener('click', function() {
  // this === link
})

Классы

JavaScript имеет довольно необычный способ реализации наследования: прототипное наследование. Прототипов наследования , хотя на мой взгляд великолепно, в отличие от большинства других популярных программных языков реализации наследства, который является классовой.

Люди, приходящие от Java или Python или другие языки, было трудно понять тонкости прототипов наследования, поэтому Комитета по EUCMAScript решила посыпать синтаксический сахар на вершине прототипического наследования, так что оно напоминает наследие на основе классовых наследований в других популярных реализациях.

Это важно: JavaScript под капотом все еще одинаково, и вы можете получить доступ к объектному прототипу обычным способом.

Определение класса

Вот как выглядит класс.

class Person {
  constructor(name) {
    this.name = name
  }
  
  hello() {
    return 'Hello, I am ' + this.name + '.'
  }
}

У класса есть идентификатор, который мы можем использовать для создания новых объектов, использующих Новый класс () Отказ

Когда объект инициализируется, Конструктор Способ называется, причем какие-либо параметры пройдены.

Урок также имеет столько методов, как это необходимо. В этом случае Привет это метод и может быть вызван на все объекты, полученные из этого класса:

const flavio = new Person('Flavio')
flavio.hello()

Наследование класса

Класс может продлить другой класс, а объекты инициализированные с использованием этого класса наследуют все методы обоих классов.

Если унаследованный класс имеет метод с тем же именем, что и один из классов выше в иерархии, ближайший метод имеет приоритет:

class Programmer extends Person {
  hello() {
    return super.hello() + ' I am a programmer.'
  }
}

const flavio = new Programmer('Flavio')
flavio.hello()

(Вышеуказанные печатающие программы « Привет, я Флавио. Я программист. »)

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

Внутри класса вы можете ссылаться на родительский класс звонков Super () Отказ

Статические методы

Обычно методы определены на экземпляре, а не на классе.

Статические методы выполняются в классе вместо этого:

class Person {
  static genericHello() {
    return 'Hello'
  }
}

Person.genericHello() //Hello

Частные методы

JavaScript не имеет встроенного способа определить частные или защищенные методы.

Есть обходные пути, но я не буду описать их здесь.

Геттерс и поселтели

Вы можете добавить методы, префиксерованные с получить или Установить Для создания Getter и Setter, которые являются двумя разными кусками кода, которые выполняются на основе того, что вы делаете: доступа к переменной или изменению ее значения.

class Person {
  constructor(name) {
    this._name = name
  }
  
  set name(value) {
    this._name = value
  }
  
  get name() {
    return this._name
  }
}

Если у вас есть только добыча, свойство не может быть установлена, и любая попытка при этом будет игнорироваться:

class Person {
  constructor(name) {
    this._name = name
  }
  
  get name() {
    return this._name
  }
}

Если у вас есть только установка, вы можете изменить значение, но не доступа к нему снаружи:

class Person {
  constructor(name) {
    this._name = name
  }
  
  set name(value) {
    this._name = value
  }
}

Параметры по умолчанию

Это Досметочное Функция, которая принимает param1 Отказ

const doSomething = (param1) => {

}

Мы можем добавить значение по умолчанию для param1 Если функция вызывается без указания параметра:

const doSomething = (param1 = 'test') => {

}

Это работает для большего количества параметров, конечно, конечно:

const doSomething = (param1 = 'test', param2 = 'test2') => {

}

Что если у вас есть уникальный объект с значениями параметров в нем?

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

const colorize = (options) => {
  if (!options) {
    options = {}
  }
  
  const color = ('color' in options) ? options.color : 'yellow'
  ...
}

С деструктурией вы можете предоставить значения по умолчанию, что упрощает код много:

const colorize = ({ color = 'yellow' }) => {
  ...
}

Если ни один объект не пропускается при вызове наших окрашиваться Функция, аналогично, мы можем назначить пустой объект по умолчанию:

const spin = ({ color = 'yellow' } = {}) => {
  ...
}

Шаблонные литералы

Шаблонные литералы позволяют вам работать с строками в новинке по сравнению с ES5 и ниже.

Синтаксис на первый взгляд очень прост, просто используйте BackTicks вместо односмысленных или двойных кавычек:

const a_string = `something`

Они уникальны, потому что они обеспечивают множество функций, которые нормальные строки, построенные с цитатами, в частности, в частности:

  • Они предлагают большой синтаксис для определения многослойных струн
  • Они обеспечивают простой способ интерполяции переменных и выражений в струнах
  • Они позволяют создавать DSLS с тегами шаблона (DSL означает, что удельный язык домена, и это, например, используется в реагированных компонентах, чтобы определить CSS для компонента)

Давайте погрузимся в каждый из них подробно.

Многослойные струны

Pre-ES6, чтобы создать строку, охватывающую на две строки, вы должны были использовать \ персонаж в конце строки:

const string =
  'first part \
second part'

Это позволяет создать строку на 2 строках, но она отображается на одной строке:

первая часть вторая часть

Чтобы сделать строку на нескольких линиях, а также явно нужно добавить \ N В конце каждой строки, как это:

const string =
  'first line\n \
second line'

или же

const string = 'first line\n' + 'second line'

Шаблонные литералы делают многослойные строки намного проще.

Как только шаблон литерала открывается с помощью BackTick, вы просто нажимаете Enter, чтобы создать новую строку, без специальных символов, и она отображается как:

const string = `Hey
this

string
is awesome!`

Имейте в виду, что пространство значимо, поэтому делает это:

const string = `First
                Second`

собирается создать такую строку:

First
                Second

Простой способ исправить эту проблему, имея пустую первую строку и добавление метода Trim () сразу после закрытия Backtick, которая будет устранить любое пространство перед первым символом:

const string = `
First
Second`.trim()

Интерполяция

Шаблонные литералы обеспечивают простой способ интерполяции переменных и выражений в строки.

Вы делаете это, используя $ {...} синтаксис:

const var = 'test'
const string = `something ${var}` //something test

внутри $ {} Вы можете добавить что-либо, даже выражения:

const string = `something ${1 + 2 + 3}`
const string2 = `something ${foo() ? 'x' : 'y'}`

Шаблон теги

Tagged Teamplates – это одна особенность, которая может выглядеть менее полезной для вас, но на самом деле она на самом деле используется множеством популярных библиотек, таких как в стиле компонентов или APOLLO, клиент/сервер GraphQL, так что важно понять, как это работает.

В стиле компонентов теги шаблона используются для определения строк CSS:

const Button = styled.button`
  font-size: 1.5em;
  background-color: black;
  color: white;
`

В тегах шаблона Apollo используются для определения схемы запроса GraphQL:

const query = gql`
  query {
    ...
  }
`

Стиль. Вуттон и GQL Шаблон теги, выделенные в те примера, просто Функции :

function gql(literals, ...expressions) {}

Эта функция возвращает строку, которая может быть результатом любой Вид вычисления.

Литералы это массив, содержащий шаблон буквального контента, токеризованного интерполяциями выражений.

Выражения Содержит все интерполяции.

Если мы возьмем пример выше:

const string = `something ${1 + 2 + 3}`

Литералы это массив с двумя предметами. Первый – что-то , строка до первой интерполяции, а вторая – пустая строка, пространство между концом первой интерполяции (у нас только один) и конец строки.

Выражения В этом случае является массивом с одним предметом 6 Отказ

Более сложный пример:

const string = `something
another ${'x'}
new line ${1 + 2 + 3}
test`

В этом случае Литералы это массив, где первый товар:

;`something
another `

второй:

;`new line `

И третья есть:

;`
new line `

Выражения В этом случае массив с двумя элементами, х и 6 Отказ

Функция, которая передается эти значения, может делать с ними что угодно, и это сила такого рода функция.

Самый простой пример реплицируют то, что делает интерполяцию строки, присоединяясь к Литералы и Выражения :

const interpolated = interpolate`I paid ${10}€`

И это как Интерполировать работает:

function interpolate(literals, ...expressions) {
  let string = ``
  for (const [i, val] of expressions) {
    string += literals[i] + val
  }
  string += literals[literals.length - 1]
  return string
}

Разрушение заданий

Учитывая объект, вы можете извлечь только некоторые значения и поместить их в именованные переменные:

const person = {
  firstName: 'Tom',
  lastName: 'Cruise',
  actor: true,
  age: 54, //made up
}

const {firstName: name, age} = person

Имя и возраст содержат желаемые значения.

Синтаксис также работает на массивах:

const a = [1,2,3,4,5]
const [first, second] = a

Это утверждение создает 3 новых переменных, получая предметы с индексом 0, 1, 4 из массива А :

Улучшенные объектные литералы

const [first, second, , , fifth] = a

В объектных литералах ES2015 получили сверхдержавы.

Проще синтаксис, чтобы включить переменные

Вместо того, чтобы сделать

const something = 'y'
const x = {
  something: something
}

ты можешь сделать

const something = 'y'
const x = {
  something
}

Опытный образец

Прототип может быть указан с

const anObject = { y: 'y' }
const x = {
  __proto__: anObject
}

супер()

const anObject = { y: 'y', test: () => 'zoo' }
const x = {
  __proto__: anObject,
  test() {
    return super.test() + 'x'
  }
}
x.test() //zoox

Динамические свойства

const x = {
  ['a' + '_' + 'b']: 'z'
}
x.a_b //z

Для петли

ES5 Назад в 2009 году введен foreach () петли. Хотя приятно, они не предложили сломать, как для Петли всегда делали.

ES2015 представил для петля , который сочетает в себе признательность foreach С возможностью сломаться:

//iterate over the value
for (const v of ['a', 'b', 'c']) {
  console.log(v);
}

//get the index as well, using `entries()`
for (const [i, v] of ['a', 'b', 'c'].entries()) {
  console.log(index) //index
  console.log(value) //value
}

Обратите внимание на использование Const Отказ Этот цикл создает новый объем в каждой итерации, поэтому мы можем безопасно использовать это вместо Пусть Отказ

Разница с Для ... в является:

  • для ... из итерации по значениям свойства
  • Для ... в имуществует имена свойств

Обещания

Обещание обычно определяется как прокси для значения, которая в конечном итоге станет доступным Отказ

Обещания – один из способов борьбы с асинхронным кодом, не написав слишком много обратных вызовов в вашем коде.

Async Функции Используйте API обещаний как их строительный блок, поэтому их понимание является фундаментальным, даже если в более новом кодексе вы, вероятно, будете использовать Async Functions вместо обещаний.

Как обещания работают, вкратце

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

На данный момент функция вызывающего абонента ждет, чтобы это либо вернуть обещание в разрешенное государству или в отклоненное государство , но как вы знаете JavaScript асинхронно, так Функция продолжает свое исполнение, в то время как обещание это работает Отказ

Какие JS API используют обещания?

В дополнение к вашему собственному коду и библиотечному коду, обещания используются стандартными современными веб-API, такие как:

Маловероятно, что в современном JavaScript вы найдете себя не Используя обещания, так что давайте начнем погрузиться прямо в них.

Создание обещания

API обещания предоставляет конструктор обещания, который вы инициализируете с использованием Новое обещание () :

let done = true

const isItDoneYet = new Promise((resolve, reject) => {
  if (done) {
    const workDone = 'Here is the thing I built'
    resolve(workDone)
  } else {
    const why = 'Still working on something else'
    reject(why)
  }
})

Как вы можете видеть, что обещание проверяет сделано Глобальная константа, и если это правда, мы возвращаем разрешенное обещание, в противном случае отклоненное обещание.

Использование решить и Отклонить Мы можем отделиться обратно значением, в приведенном выше случае мы просто вернем строку, но это может быть объектом.

Потребление обещания

В последнем разделе мы представили, как создается обещание.

Теперь давайте посмотрим, как обещание может быть потребляется или используется.

const isItDoneYet = new Promise()
//...

const checkIfItsDone = () => {
  isItDoneYet
    .then(ok => {
      console.log(ok)
    })
    .catch(err => {
      console.error(err)
    })
}

Бег checkifitsdone () будет выполнять isitdoneyet () Обещайте и будете ждать, пока это разрешится, используя Тогда Обратный вызов, и если есть ошибка, она будет справиться с этим в поймать Перезвоните.

Цепочка

Обещание может быть возвращено в другое обещание, создавая цепочку обещаний.

Отличный пример цепочки обещаний дается Fetch API , слой на вершине API XMLHTTPREQUEST, который мы можем использовать для получения ресурса и очереди цепочки обещаний для выполнения при получении ресурса.

API Fetch – это механизм, основанный на обещании, и звонит fetch () эквивалентно определению нашего собственного обещания, используя Новое обещание () Отказ

Пример цепочки обещаний

const status = response => {
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  }
  return Promise.reject(new Error(response.statusText))
}

const json = response => response.json()

fetch('/todos.json')
  .then(status)
  .then(json)
  .then(data => {
    console.log('Request succeeded with JSON response', data)
  })
  .catch(error => {
    console.log('Request failed', error)
  })

В этом примере мы называем fetch () Чтобы получить список предметов Todo из todos.json Файл найден в корне домена, и мы создаем цепочку обещаний.

Бег fetch () Возвращает ответ , у которого много свойств, и внутри тех, которые мы ссылаемся:

  • Статус числовое значение, представляющее код состояния HTTP
  • stustustext , сообщение о состоянии, который является Хорошо Если запрос преуспел

ответ также имеет JSON () Способ, который возвращает обещание, которое будет разрешено с содержанием тела, обработанного и преобразованного в JSON.

Так что дали те помещения, это то, что происходит: первое обещание в цепочке – это функция, которую мы определили, называемые Статус () , это проверяет состояние ответа и, если это не ответ на успех (между 200 и 299), он отклоняет обещание.

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

Если это удается вместо этого, он вызывает функцию JSON (), которую мы определили. С момента предыдущего обещания, когда успешно вернуло ответ Объект, мы получаем его как вход ко второму обещанию.

В этом случае мы возвращаем данные JSON, обработанные, поэтому третье обещание получает JSON напрямую:

.then((data) => {
  console.log('Request succeeded with JSON response', data)
})

И мы входим в систему до консоли.

Обработка ошибок

В приведенном выше примере, в предыдущем разделе у нас было поймать Это было добавлено к цепочке обещаний.

Когда что-то в цепочке обещаний терпят неудачу и повышает ошибку или отклоняет обещание, контроль идет к ближайшему поймать () Заявление по цепочке.

new Promise((resolve, reject) => {
  throw new Error('Error')
}).catch(err => {
  console.error(err)
})

// or

new Promise((resolve, reject) => {
  reject('Error')
}).catch(err => {
  console.error(err)
})

Каскадные ошибки

Если внутри поймать () Вы поднимаете ошибку, вы можете добавить вторую поймать () справиться с этим и так далее.

new Promise((resolve, reject) => {
  throw new Error('Error')
})
  .catch(err => {
    throw new Error('Error')
  })
  .catch(err => {
    console.error(err)
  })

Оробщание обещания

Обещание. Все ()

Если вам нужно синхронизировать разные обещания, Обещание. Все () Помогает вам определить список обещаний и выполнять что-то, когда все они решены.

Пример:

const f1 = fetch('/something.json')
const f2 = fetch('/something2.json')

Promise.all([f1, f2])
  .then(res => {
    console.log('Array of results', res)
  })
  .catch(err => {
    console.error(err)
  })

Синтаксис назначения деструкции ES2015 позволяет вам также сделать

Promise.all([f1, f2]).then(([res1, res2]) => {
  console.log('Results', res1, res2)
})

Вы не ограничиваются использованием извлекать Конечно, Любое обещание хорошо, чтобы пойти Отказ

Promess.race ()

Promess.race () Работает как только одна из обещаний, которые вы проходите к нему, решаются, и он запускает прикрепленный обратный вызов только один раз с результатом первого обещания.

Пример:

const promiseOne = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one')
})
const promiseTwo = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two')
})

Promise.race([promiseOne, promiseTwo]).then(result => {
  console.log(result) // 'two'
})

Модули

Модули ES – это стандарт ECMAScript для работы с модулями.

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

Этот процесс стандартизации, завершенный с ES2015, и браузеры начали реализовывать этот стандарт, пытаясь сохранить все хорошо выровненные, работать все таким же образом, и теперь модули ES поддерживаются в Chrome, Safari, Edge и Firefox (с версии 60).

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

Синтаксис модулей ES

Синтаксис для импорта модуля:

import package from 'module-name'

в то время как Commonjs использует

const package = require('module-name')

Модуль – это файл JavaScript, который Экспорт Один или несколько значений (объекты, функции или переменные), используя Экспорт ключевое слово. Например, этот модуль экспортирует функцию, которая возвращает строку в верхнем регистре:

export default str => str.toUpperCase()

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

Теперь Любой другой модуль JavaScript Может импортировать функциональные возможности, предлагаемые Optlections.js, импортируя его.

Страница HTML может добавить модуль, используя PT> Тег с SP ecial type = "m Оделю" Атрибут:

Важно отметить, что любой сценарий, загруженный Тип = "Модуль" загружен в строгий режим.

В этом примере Верхний >js Модуль определяет Экспорт по умолчанию Поэтому, когда мы им импортируем, мы можем назначить его имя, которое мы предпочитаем:

import toUpperCase from './uppercase.js'

И мы можем использовать это:

toUpperCase('test') //'TEST'

Вы также можете использовать абсолютный путь для импорта модуля, для эталонных модулей, определенных на другом домене:

import toUpperCase from 'https://flavio-es-modules-example.glitch.me/uppercase.js'

Это также допустимый синтаксис импорта:

import { toUpperCase } from '/uppercase.js'
import { toUpperCase } from '../uppercase.js'

Это не:

import { toUpperCase } from 'uppercase.js'
import { toUpperCase } from 'utils/uppercase.js'

Это либо абсолютно, либо имеет ./ или / до имени.

Другие варианты импорта/экспорта

Мы видели этот пример выше:

export default str => str.toUpperCase()

Это создает один экспорт по умолчанию. В файле, однако, вы можете экспортировать более одной вещи, используя этот синтаксис:

const a = 1
const b = 2
const c = 3

export { a, b, c }

Другой модуль может импортировать все эти экспорта, используя

import * from 'module'

Вы можете импортировать только несколько из этих экспорта, используя задание по разрушению:

import { a } from 'module'
import { a, b } from 'module'

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

import { a, b as two } from 'module'

Вы можете импортировать экспорт по умолчанию, и любой экспорт не по умолчанию по имени, как в этом общим импоте RACT:

import React, { Component } from 'react'

Вы можете увидеть пример модулей ES здесь: https://glitch.com/Edit/#!/flavio-es-modules-examphath?phath=index.html.

Рост

Модули выбираются с использованием CORS. Это означает, что если вы справляетесь с сценариями из других доменов, они должны иметь действительный заголовок CORS, который позволяет погрузку на сайт (например, Access-Control-Allow-origine: * )

Как насчет браузеров, которые не поддерживают модули?

Используйте комбинацию Тип = "Модуль" и Nomodule :


Упаковка модулей

Модули ES являются одной из самых больших функций, представленных в современных браузерах. Они являются частью ES6, но путь к реализации их долго.

Теперь мы можем использовать их! Но мы также должны помнить, что имея более нескольких модулей, на наших страницах будет использоваться производительность, поскольку это еще один шаг, который браузер должен выполняться во время выполнения.

Вероятно, что WebPack, вероятно, по-прежнему будет огромным игроком, даже если модули ES приземляются в браузере, но имея такую функцию, непосредственно построенную на языке, огромна для объединения того, как модули работают на стороне клиента и на Node.js.

Новые строковые методы

Любое строковое значение получило несколько новых методов экземпляра:

  • повторить()
  • CodePointat ()

повторить()

Повторяет строки на указанное количество раз:

'Ho'.repeat(3) //'HoHoHo'

Возвращает пустую строку, если нет параметра, или параметр – 0 Отказ Если параметр отрицательный, вы получите assiteError.

CodePointat ()

Этот метод можно использовать для обработки символов Unicode, которые не могут быть представлены одним 16-битной единицей Unicode, но вместо этого нужно 2.

Использование Carcodeat () Вам нужно извлечь первый, а второй и объединить их. Использование CodePointat () Вы получаете весь персонаж в одном звонке.

Например, этот китайский характер “?” состоит из 2 частей UTF-16 (Unicode):

"?".charCodeAt(0).toString(16) //d842
"?".charCodeAt(1).toString(16) //dfb7

Если вы создаете новый символ, объединяя эти символы Unicode:

"\ud842\udfb7" //"?"

Вы можете получить тот же результат знак CodePointat () :

"?".codePointAt(0) //20bb7

Если вы создаете новый символ, объединяя эти символы Unicode:

"\u{20bb7}" //"?"

Больше на Unicode и работает с ним в моем Руководство ЮНИКОД Отказ

Новые объектные методы

ES2015 ввел несколько статических методов под пространством пространства объекта:

  • Объект. () Определяет, являются ли два значения одинаковым значением
  • Объект.assign () используется для неглубокого копирования объекта
  • Object.SetPrototyepef Устанавливает прототип объекта

Object.is ()

Эти методы направлены на сопоставление значений.

Применение:

Object.is(a, b)

Результат всегда ложь пока не:

  • А и B такие же точный объект
  • А и B равные строки (строки равны при составных той же персонажами)
  • А и B равные числа (числа равны, когда их значение равно)
  • А и B оба undefined , оба null , оба Нан , оба правда или оба ложный

0 и -0 Различные значения в JavaScript, поэтому обратите внимание в этом особом случае (конвертировать все на +0 Использование оператора + Унарный оператор до сравнения, например).

Объект.assign ()

Введен в ES2015 Этот метод копирует все Перечислимые собственные свойства одного или нескольких предметов в другое.

Его основное использование является создание неглубокой копии объекта.

const copied = Object.assign({}, original)

Быть неглубокой копией, значения клонированы, а ссылки на объекты копируются (не сами по себе объекты), поэтому, если вы редактируете свойство объекта в исходном объекте, это также модифицировано также в скопированном объекте, поскольку ссылка на внутренний объект такой же:

const original = {
  name: 'Fiesta',
  car: {
    color: 'blue'
  }
}

const copied = Object.assign({}, original)

original.name = 'Focus'
original.car.color = 'yellow'

copied.name //Fiesta
copied.car.color //yellow

Я упомянул «один или несколько»:

const wisePerson = {
  isWise: true
}
const foolishPerson = {
  isFoolish: true
}
const wiseAndFoolishPerson = Object.assign({}, wisePerson, foolishPerson)

console.log(wiseAndFoolishPerson) //{ isWise: true, isFoolish: true }

Object.SetPrototyeeP ()

Установите прототип объекта. Принимает два аргумента: объект и прототип.

Применение:

Object.setPrototypeOf(object, prototype)

Пример:

const animal = {
  isAnimal: true
}
const mammal = {
  isMammal: true
}

mammal.__proto__ = animal
mammal.isAnimal //true

const dog = Object.create(animal)

dog.isAnimal  //true
console.log(dog.isMammal)  //undefined

Object.setPrototypeOf(dog, mammal)

dog.isAnimal //true
dog.isMammal //true

Оператор распространения

Вы можете расширить массив, объект или строку с использованием оператора SPRECT ...

Давайте начнем с примера массива. Дано

const a = [1, 2, 3]

Вы можете создать новый массив, используя

const b = [...a, 4, 5, 6]

Вы также можете создать копию массива, используя

const c = [...a]

Это работает для объектов. Клонировать объект с:

const newObj = { ...oldObj }

Использование строк оператор спреда создает массив с каждым символом в строке:

const hey = 'hey'
const arrayized = [...hey] // ['h', 'e', 'y']

У этого оператора есть несколько довольно полезных приложений. Наиболее важной является возможность использовать массив в качестве аргумента функций очень простой способ:

(В прошлом вы можете сделать это, используя F.apply (NULL, A) Но это не так хоросно и читабельно.)

Элемент отдыха полезен при работе с Раскрытие массива :

const numbers = [1, 2, 3, 4, 5]
[first, second, ...others] = numbers

и Распространение элементов :

const numbers = [1, 2, 3, 4, 5]
const sum = (a, b, c, d, e) => a + b + c + d + e
const sum = sum(...numbers)

ES2018 вводит свойства отдыха, которые одинаковы, но для объектов.

Отдых свойства :

const { first, second, ...others } = {
  first: 1,
  second: 2,
  third: 3,
  fourth: 4,
  fifth: 5
}

first // 1
second // 2
others // { third: 3, fourth: 4, fifth: 5 }

Распространение свойств Позвольте нам создать новый объект, объединяя свойства объекта, прошедшего после оператора распространения:

const items = { first, second, ...others }
items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }

Набор

Установленная структура данных позволяет нам добавлять данные в контейнер.

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

Инициализировать набор

Набор инициализируется приводом:

const s = new Set()

Добавить товары в комплект

Вы можете добавить элементы в комплект, используя Добавить Метод:

s.add('one')
s.add('two')

Набор только хранит уникальные элементы, так что звонит S.ADD («Один») Несколько раз не добавят новые элементы.

Вы не можете добавить несколько элементов в комплект одновременно. Вам нужно позвонить Добавить () много раз.

Проверьте, находится ли элемент в наборе

После того, как элемент находится в наборе, мы можем проверить, содержит ли этот набор:

s.has('one') //true
s.has('three') //false

Удалить элемент из установленного ключа

Используйте Удалить () Метод:

s.delete('one')

Определите количество предметов в наборе

Используйте Размер имущество:

s.size

Удалить все предметы из набора

Используйте Очистить () Метод:

s.clear()

Итайте предметы в наборе

Используйте Клавиши () или Значения () Методы – они эквивалентны:

for (const k of s.keys()) {
  console.log(k)
}

for (const k of s.values()) {
  console.log(k)
}

Записи () Метод возвращает итератор, который вы можете использовать следующим образом:

const i = s.entries()
console.log(i.next())

Призыв i.next () вернет каждый элемент как {Значение,} объект, пока итератор не заканчивается, в какой момент сделано это правда Отказ

Вы также можете использовать метод Foreach () на наборе:

s.forEach(v => console.log(v))

Или вы можете просто использовать набор в LOOP AF..OF:

for (const k of s) {
  console.log(k)
}

Инициализировать набор со значениями

Вы можете инициализировать набор с набором значений:

const s = new Set([1, 2, 3, 4])

Преобразовать набор клавиш в массив

const a = [...s.keys()]

// or

const a = [...s.values()]

Слабый

Слабое задача – это особый вид набора.

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

Вот основные различия:

  1. Вы не можете повторять слабые
  2. Вы не можете очистить все предметы из слабых
  3. Вы не можете проверить его размер

Слабое значение обычно используется кодом рамочного уровня и выставляет только эти методы:

  • Добавлять()
  • имеет()
  • Удалить()

карта

Структура данных карты позволяет нам ассоциировать данные к ключу.

До ES6

До его введения люди обычно использовали объекты в качестве карт, связывая какой-то объект или значение для определенного значения ключей:

const car = {}
car['color'] = 'red'
car.owner = 'Flavio'
console.log(car['color']) //red
console.log(car.color) //red
console.log(car.owner) //Flavio
console.log(car['owner']) //Flavio

Введите карту

ES6 представила структуру данных карты, предоставляя нам правильный инструмент для обработки такого рода организации данных.

Карта инициализируется по вызову:

const m = new Map()

Добавить товары на карту

Вы можете добавлять элементы на карту, используя Установить Метод:

m.set('color', 'red')
m.set('age', 2)

Получить предмет на карте по ключу

И вы можете получить элементы из карты, используя получить :

const color = m.get('color')
const age = m.get('age')

Удалить элемент с карты по ключу

Используйте Удалить () Метод:

m.delete('color')

Удалить все предметы с карты

Используйте Очистить () Метод:

m.clear()

Проверьте, содержит ли карта элемент по ключу

Используйте имеет () Метод:

const hasColor = m.has('color')

Найти количество предметов на карте

Используйте Размер имущество:

const size = m.size

Инициализировать карту со значениями

Вы можете инициализировать карту с набором значений:

const m = new Map([['color', 'red'], ['owner', 'Flavio'], ['age', 2]])

Клавиши карты

Как и любое значение (объект, массив, строка, номер), можно использовать в качестве значения ввода значения ключа элемента карты, Любое значение может быть использовано в качестве ключа даже объекты.

Если вы попытаетесь получить несуществующий ключ, используя Получить () из карты, это вернется undefined Отказ

Странные ситуации, которые вы почти никогда не найдете в реальной жизни

const m = new Map()
m.set(NaN, 'test')
m.get(NaN) //test

const m = new Map()
m.set(+0, 'test')
m.get(-0) //test

Итерация на карте Ключи

Карта предлагает Клавиши () Метод мы можем использовать для повторения всех клавиш:

for (const k of m.keys()) {
  console.log(k)
}

Итерация по ценам карты

Объект карты предлагает Значения () Метод мы можем использовать для повторения всех значений:

for (const v of m.values()) {
  console.log(v)
}

Итерация за ключом карты, ценные пары

Объект карты предлагает Записи () Метод мы можем использовать для повторения всех значений:

for (const [k, v] of m.entries()) {
  console.log(k, v)
}

что можно упростить

for (const [k, v] of m) {
  console.log(k, v)
}

Преобразуйте клавиши карты в массив

const a = [...m.keys()]

Преобразовать значения карты в массив

const a = [...m.values()]

Слабый

Слабый ход – это особый вид карты.

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

Вот основные различия:

  1. Вы не можете повторять ключи или значения (или значения ключей) слабого канала
  2. Вы не можете очистить все элементы из слабака
  3. Вы не можете проверить его размер

Слабый ход предоставляет те методы, которые эквивалентны картам:

  • Получить (k)
  • Set (k, v)
  • имеет (к)
  • Удалить (k)

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

Генераторы

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

См. Полное руководство генераторов JavaScript для подробного объяснения темы.

Код решает, что он должен ждать, поэтому он позволяет другим кодам «в очереди», чтобы запустить и сохраняет право возобновить свои операции «Когда вещь, которую она ждет».

Все это сделано с одним простом ключевым словом: доходность Отказ Когда генератор содержит это ключевое слово, выполнение остановлено.

Генератор может содержать много доходность Ключевые слова, таким образом, останавливаются несколько раз, и он идентифицируется * Функция Ключевое слово, которое не должно быть путать с оператором разыскивателя указателя, используемым в языках программирования более низкого уровня, такими как C, C ++ или GO.

Генераторы позволяют целые новые парадигмы программирования в JavaScript, что позволяет:

  • 2-контактная связь во время работы генератора
  • долгоживутся, пока петли, которые не замораживают вашу программу

Вот пример генератора, который объясняет, как все это работает.

function *calculator(input) {
    var doubleThat = 2 * (yield (input / 2))
    var another = yield (doubleThat)
    return (input * doubleThat * another)
}

Мы инициализируем это с

const calc = calculator(10)

Затем мы запускаем итератор на нашем генераторе:

calc.next()

Эта первая итерация начинает итератор. Код возвращает этот объект:

{
  done: false
  value: 5
}

Что происходит: код запускает функцию, с вход Как это было передано в конструкторе генератора. Он проходит до тех пор, пока не достигнет доходность и возвращает содержание доходность : вход/ Отказ Таким образом, мы получили значение 5, а указание, что итерация не выполняется (функция просто приостановлена).

Во второй итерации мы проходим значение 7 :

calc.next(7)

И что мы вернулись, это:

{
  done: false
  value: 14
}

7 был размещен как значение Дублетат Отказ Важно: вы можете прочитать как ввод/2 Был аргумент, но это просто возвращаемое значение первой итерации. Теперь мы пропускаем это и используем новое входное значение, 7 И умножьте его на 2.

Затем мы достигаем второй доходности, и это возвращает Дублетат поэтому возвращенное значение – 14 Отказ

В следующем и последнем, итерации мы проходим в 100

calc.next(100)

и взамен мы получили

{
  done: true
  value: 14000
}

Поскольку итерация сделана (не найдено больше ключевых слов доходности), и мы просто вернемся (Вход * DoubleThat * другой) что составляет 10 * 14 * 100 Отказ

Это были особенности, представленные в ES2015. Давайте теперь погрузимся в ES2016, что намного меньше по объему.

Array.Prototype. INCludes ()

Эта функция вводит более читаемый синтаксис для проверки, содержит ли массив элемент.

С ES6 и ниже, чтобы проверить, содержал ли массив элемент, который вы должны были использовать Индекс , который проверяет индекс в массиве и возвращает -1 Если элемент там нет.

С -1 оценивается как истинное значение, вы могли бы не делать, например

if (![1,2].indexOf(3)) {
  console.log('Not found')
}

С этой функцией, представленной в ES7, мы можем сделать

if (![1,2].includes(3)) {
  console.log('Not found')
}

Оператор Exponentiation ** эквивалент Math.pow () , но принес на язык вместо того, чтобы быть библиотечной функцией.

Math.pow(4, 2) == 4 ** 2

Эта функция является хорошим дополнением для математических приложений JS.

** Оператор стандартизирован на многих языках, включая Python, Ruby, Matlab, Lua, Perl и многих других.

Это были особенности, представленные в 2016 году. Давайте теперь погрузимся в 2017 году

Цель струнного прокладки – это Добавить символы в строку Итак, это достигает определенной длины Отказ

ES2017 вводит два Строка Методы: Padstart () и Poadend () Отказ

padStart(targetLength [, padString])
padEnd(targetLength [, padString])

Использование образца:

Object.values ()

Этот метод возвращает массив, содержащий все значения собственного объекта.

Применение:

const person = { name: 'Fred', age: 87 }
Object.values(person) // ['Fred', 87]

Object.values () Также работает с массивами:

const people = ['Fred', 'Tony']
Object.values(people) // ['Fred', 'Tony']

Object.entries ()

Этот метод возвращает массив, содержащий все свойства объекта, как массив [ключ, значение] Пары.

Применение:

const person = { name: 'Fred', age: 87 }
Object.entries(person) // [['name', 'Fred'], ['age', 87]]

Object.entries () Также работает с массивами:

const people = ['Fred', 'Tony']Object.entries(people) // [['0', 'Fred'], ['1', 'Tony']]

Object.GetownPropertyDescriptors ()

Этот метод возвращает все собственные (не наследуемые) дескрипторы объекта объекта.

Любой объект в JavaScript имеет набор свойств, и каждый из этих свойств имеет дескриптор.

Дескриптор представляет собой набор атрибутов свойства, и он состоит из подмножества следующего:

  • ценность : значение собственности
  • Пирена : true, что имущество может быть изменено
  • получить : Функция Gotter для свойства, называемая при чтении свойства
  • Установить : функция сеттера для свойства, вызываемая, когда свойство установлено значение значение
  • настраивается : Если false, свойство не может быть удалена, ни какой атрибут не может быть изменен, кроме его значения
  • перечислимый : true, если собственность перечисляется

Object.GetownPropertyDescriptors (OBJ) Принимает объект и возвращает объект с набором дескрипторов.

Каким образом это полезно?

ES6 дал нам Объект.assign () , которые копируют все перечислимые собственные свойства от одного или нескольких объектов и вернуть новый объект.

Однако есть проблема с этим, потому что она не правильно копирует свойства с атрибутами не по умолчанию.

Если объект, например, имеет только сеттер, он не правильно скопирован на новый объект, используя Объект.assign () Отказ

Например с

const person1 = {
    set name(newName) {
        console.log(newName)
    }
}

Это не будет работать:

const person2 = {}
Object.assign(person2, person1)

Но это будет работать:

const person3 = {}Object.defineProperties(person3,  Object.getOwnPropertyDescriptors(person1))

Как вы можете видеть с простым тестом консоли:

person1.name = 'x'
"x"

person2.name = 'x'

person3.name = 'x'
"x"

человек2 Пропускает сеттер, он не был скопирован.

Такое же ограничение идет для мелких клонирующих объектов с Object.Create () Отказ

Комиссионные запятые

Эта функция позволяет иметь комиссионные запятые в функциональных объявлениях, а в функциях вызовы:

const doSomething = (var1, var2,) => {
  //...
}

doSomething('test2', 'test2',)

Это изменение побуждает разработчиков остановить уродливую «запятую в начале линии» привычки.

Async Функции

JavaScript превратился в очень короткое время от обратных вызовов к обещаниям (ES2015), а поскольку Asynchronous JavaScript is2017 даже проще с синтаксисом Async/await.

Async Functions – это сочетание обещаний и генераторов, и в основном они являются более высоким уровнем абстракции по поводу обещаний. Позвольте мне повторить: Async/await построен на обещаниях Отказ

Почему был представлен Async/await?

Они уменьшают ботинтуру вокруг обещаний, а «не ломает цепь» ограничение цепочки обещаний.

Когда обещания были введены в ES2015, они должны были решить проблему с асинхронным кодом, и они, но за 2 года, которые разлучали ES2015 и ES2017, было ясно, что Обещания не могли быть окончательным решением Отказ

Обещания были представлены, чтобы решить знаменитый Обратный вызов Ад Проблема, но они ввели сложность самостоятельно, и синтаксис сложности.

Они были хорошими примитивами, которые могут быть подвержены разработчикам лучший синтаксис, поэтому, когда у нас было правильно, мы получили Async Функции Отказ

Они заставляют код похож на синхронный, но он асинхронный и не блокирующий за кулисами.

Как это работает

Async Function возвращает обещание, как в этом примере:

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

Когда вы хотите Позвоните Эта функция вы представляете ждать и Код вызова остановится до тех пор, пока обещание не будет разрешено или отклонить Отказ Одно предупреждение: функция клиента должна быть определена как async Отказ Вот пример:

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

Быстрый пример

Это простой пример Async/a enaiq, используемый для управления функцией асинхронно:

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

console.log('Before')
doSomething()
console.log('After')

Приведенный выше код будет распечатать следующее в консоль браузера:

Before
After
I did something //after 3s

Обещать все вещи

Подготовка async Ключевое слово для любой функции означает, что функция вернет обещание.

Даже если он не делает так явно, он внутренне сделает его вернуть обещание.

Вот почему этот код действителен:

const aFunction = async () => {
  return 'test'
}

aFunction().then(alert) // This will alert 'test'

И это так же, как:

const aFunction = async () => {
  return Promise.resolve('test')
}

aFunction().then(alert) // This will alert 'test'

Код намного продвигается для чтения

Как вы можете видеть в примере выше, наш код выглядит очень просто. Сравните его с кодом, используя простые обещания, с функциями цепочки и обратного вызова.

И это очень простой пример, основные преимущества возникнут, когда код гораздо сложнее.

Например, вот как вы получите ресурс JSON, а также разбирать его, используя обещания:

const getFirstUserData = () => {
  return fetch('/users.json') // get users list
    .then(response => response.json()) // parse JSON
    .then(users => users[0]) // pick first user
    .then(user => fetch(`/users/${user.name}`)) // get user data
    .then(userResponse => response.json()) // parse JSON
}

getFirstUserData()

И вот та же функциональность, предусмотренная с использованием avait/async:

const getFirstUserData = async () => {
  const response = await fetch('/users.json') // get users list
  const users = await response.json() // parse JSON
  const user = users[0] // pick first user
  const userResponse = await fetch(`/users/${user.name}`) // get user data
  const userData = await user.json() // parse JSON
  return userData
}

getFirstUserData()

Несколько Async функций последовательно

Функции Async могут быть очень легко присоединены, а синтаксис гораздо более читаемый, чем с простыми обещаниями:

const promiseToDoSomething = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 10000)
  })
}

const watchOverSomeoneDoingSomething = async () => {
  const something = await promiseToDoSomething()
  return something + ' and I watched'
}

const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
  const something = await watchOverSomeoneDoingSomething()
  return something + ' and I watched as well'
}

watchOverSomeoneWatchingSomeoneDoingSomething().then(res => {
  console.log(res)
})

Будет печатать:

I did something and I watched and I watched as well

Легче отладка

Отладка обещаний трудно, потому что отладчик не пойдет на асинхронный код.

Async/await делает это очень легко, потому что для компилятора это так же, как синхронный код.

Общая память и атомная

WebWorkers используются для создания многопоточных программ в браузере.

Они предлагают протокол обмена сообщениями по событиям. Поскольку ES2017, вы можете создать общий массив памяти между веб-работниками и их создателем, используя SharedArrayBuffer Отказ

Так как неизвестно, сколько времени пишут до общей порции памяти, занимает распространение, Atomics Являются ли способ обеспечить то, что при чтении ценности будет завершена любой вид операции письма.

Более подробнее для этого можно найти в специфическом предложении , который с тех пор был реализован.

Это было ES2017. Позвольте мне теперь представить функции ES2018

Свойства отдыха/распространения

ES2015 представила концепцию Элемент отдыха При работе с Раскрытие массива :

const numbers = [1, 2, 3, 4, 5]
[first, second, ...others] = numbers

и Распространение элементов :

const numbers = [1, 2, 3, 4, 5]
const sum = (a, b, c, d, e) => a + b + c + d + e
const sum = sum(...numbers)

ES2018 вводит то же самое, но для объектов.

Отдых свойства :

const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }

first // 1
second // 2
others // { third: 3, fourth: 4, fifth: 5 }

Распространение свойств Разрешить создать новый объект, объединяя свойства объекта, прошедшего после оператора распространения:

const items = { first, second, ...others }
items //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 }

Асинхронная итерация

Новая конструкция для ожидания Позволяет использовать асинхронный объект в качестве итерации петли:

for await (const line of readLines(filePath)) {
  console.log(line)
}

Так как это использует ждать , вы можете использовать его только внутри async Функции, как нормальный ждать Отказ

Обещание. Прототип. Финально ()

Когда обещание выполняется, успешно это называет тогда () Методы, один за другим.

Если что-то терпит неудачу во время этого, тогда () Методы прыгают и поймать () Способ выполнен.

Наконец () Позвольте вам запустить код независимо от успешного или не успешного выполнения обещания:

fetch('file.json')
  .then(data => data.json())
  .catch(error => console.error(error))
  .finally(() => console.log('finished'))

Улучшения регулярного выражения

ES2018 представила ряд улучшений в отношении регулярных выражений. Я рекомендую свое учебное пособие на них, доступно в https://flaviocopes.com/javascript-regular-expressions/ Отказ

Вот специфические дополнения ES2018.

Утверждения Regex Bookbehind: Сопоставьте строку в зависимости от того, что предшествует этому

Это lookahead: вы используете ? = Чтобы сопоставить строку, которая сопровождается определенной подстрокой:

/Roger(?=Waters)/

/Roger(?= Waters)/.test('Roger is my dog') //false
/Roger(?= Waters)/.test('Roger is my dog and Roger Waters is a famous musician') //true

?! выполняет обратную работу, сопоставление, если строка – не с последующим определенной подстрокой:

/Roger(?!Waters)/

/Roger(?! Waters)/.test('Roger is my dog') //true
/Roger(?! Waters)/.test('Roger Waters is a famous musician') //false

Allyaheads используют ? = символ. Они уже были доступны.

Смотреть больше отходов , новая особенность, использует ? <= Отказ

/(?<=Roger) Waters/

/(?<=Roger) Waters/.test('Pink Waters is my dog') //false
/(?<=Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //true

ОБЕСПЕЧЕНИЕ отрицается, используя ? :

/(?

Свойство Unicode Essapes \ p {…} и \ p {…}

В шаблоне регулярного выражения вы можете использовать \ D соответствовать любой цифру, \ S Чтобы соответствовать любому персонажу, это не белое пространство, \ W соответствовать любому буквенно-цифровому символу и так далее.

Эта новая функция расширяет эту концепцию всех символов Unicode, представляющих \ p {} И отрицание \ P {} Отказ

Любой символ Unicode имеет набор свойств. Например Сценарий Определяет языковую семью, Ascii Это логическое значение, которое верно для персонажей ASCII и так далее. Вы можете поставить это свойство в графические скобки, а регулярное выражение проверит, чтобы быть правдой:

/^\p{ASCII}+$/u.test('abc')   //✅
/^\p{ASCII}+$/u.test('ABC@')  //✅
/^\p{ASCII}+$/u.test('ABC?') //❌

Ascii_hex_digit Это еще одно логическое свойство, которая проверяет, содержит ли строки только в действительности шестнадцатеричных цифр:

/^\p{ASCII_Hex_Digit}+$/u.test('0123456789ABCDEF') //✅
/^\p{ASCII_Hex_Digit}+$/u.test('h')                //❌

Есть много других логических свойств, которые вы просто проверяете, добавив свое имя в скобках графа, в том числе Заглавные буквы , Строчные буквы , White_space , Алфавит , Emoji и больше:

/^\p{Lowercase}$/u.test('h') //✅
/^\p{Uppercase}$/u.test('H') //✅

/^\p{Emoji}+$/u.test('H')   //❌
/^\p{Emoji}+$/u.test('??') //✅

В дополнение к этим двоичным свойствам вы можете проверить любой из свойств символов Unicode для соответствия определенному значению. В этом примере я проверяю, написана ли строка на греческом или латинском алфавите:

/^\p{Script=Greek}+$/u.test('ελληνικά') //✅
/^\p{Script=Latin}+$/u.test('hey') //✅

Узнайте больше о всех свойствах, которые вы можете использовать непосредственно на предложение Отказ

Названные захватывающие группы

В ES2018 Pointing Group может быть назначена имени, а не просто назначение слота в массиве результата:

const re = /(?\d{4})-(?\d{2})-(?\d{2})/
const result = re.exec('2015-01-02')

// result.groups.year === '2015';
// result.groups.month === '01';
// result.groups.day === '02';

Флаг S для регулярных выражений

S Флаг, короткая для Одна линия , вызывает Отказ соответствовать новым символам линии. Без этого точка соответствует регулярным персонажам, но не новая строка:

/hi.welcome/.test('hi\nwelcome') // false
/hi.welcome/s.test('hi\nwelcome') // true

Esnext.

Что дальше? Esnext.

ESNext – это имя, которое всегда указывает на следующую версию JavaScript.

Текущая версия Ecmascript – ES2018 Отказ Он был выпущен в июне 2018 года.

Исторически JavaScript издания были стандартизированы летом, поэтому мы можем ожидать Ecmascript 2019 быть выпущенным летом 2019 года.

Таким образом, на момент написания, ES2018 был выпущен, и ESNEXT IS2019.

Предложения по стандарту ECMAScript организованы на этапах. Этапы 1-3 являются инкубатором новых функций, а функции достижения этапа 4 доработаны как часть нового стандарта.

На момент написания у нас есть ряд функций в Этап 4 Отказ Я познакомим их в этом разделе. Последние версии основных браузеров уже должны реализовать большинство из них.

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

На этапе 3 есть другие функции, которые могут быть повышены до этапа 4 в ближайшие несколько месяцев, и вы можете проверить их на этом репозитории GitHUB: https://github.com/tc39/proposals Отказ

Array.Prototype. {Flat, flatmap}

квартира () является новым методом экземпляра Array, который может создать одномерный массив из многомерного массива.

Пример:

['Dog', ['Sheep', 'Wolf']].flat()
//[ 'Dog', 'Sheep', 'Wolf' ]

По умолчанию он только «квартиры» до одного уровня, но вы можете добавить параметр, чтобы установить количество уровней, которые вы хотите настроить массив. Установите это на Бесконечность иметь неограниченный уровень:

['Dog', ['Sheep', ['Wolf']]].flat()
//[ 'Dog', 'Sheep', [ 'Wolf' ] ]

['Dog', ['Sheep', ['Wolf']]].flat(2)
//[ 'Dog', 'Sheep', 'Wolf' ]

['Dog', ['Sheep', ['Wolf']]].flat(Infinity)
//[ 'Dog', 'Sheep', 'Wolf' ]

Если вы знакомы с JavaScript карта () Способ массива, вы знаете, что используя его, вы можете выполнить функцию на каждом элементе массива.

FlatMap () Это новый метод экземпляра массива, который сочетает в себе квартира () с карта () Отказ Это полезно при вызове функции, которая возвращает массив на карте () обратный вызов, но вы хотите, чтобы ваш результат был плоским:

['My dog', 'is awesome'].map(words => words.split(' '))
//[ [ 'My', 'dog' ], [ 'is', 'awesome' ] ]

['My dog', 'is awesome'].flatMap(words => words.split(' '))
//[ 'My', 'dog', 'is', 'awesome' ]

Дополнительный переплет

Иногда нам не нужно иметь параметр, привязанный к блоку Catch Try/Catch.

Мы ранее должны были сделать:

try {
  //...
} catch (e) {
  //handle error
}

Даже если нам никогда не пришлось использовать е проанализировать ошибку. Теперь мы можем просто опускать это:

try {
  //...
} catch {
  //handle error
}

Объект.Fromentries ()

Объекты имеют Записи () Метод, поскольку ES2017.

Он возвращает массив, содержащий все свойства объекта, как массив [ключ, значение] Пары:

const person = { name: 'Fred', age: 87 }
Object.entries(person) // [['name', 'Fred'], ['age', 87]]

ES2019 представляет новый Объект.Fromentries () Способ, который может создать новый объект из такого массива свойств:

const person = { name: 'Fred', age: 87 }
const entries = Object.entries(person)
const newPerson = Object.fromEntries(entries)

person !== newPerson //true 

String.Prototype. {TrimStart, Trimend}

Эта особенность была частью V8/Chrome уже почти год, и она будет стандартизирована в ES2019.

TrimStart ()

Верните новую строку с удаленным белым пространством от начала исходной строки

'Testing'.trimStart() //'Testing'
' Testing'.trimStart() //'Testing'
' Testing '.trimStart() //'Testing '
'Testing'.trimStart() //'Testing'

Trimend ()

Верните новую строку с удаленным белым пространством от конца исходной строки

'Testing'.trimEnd() //'Testing'
' Testing'.trimEnd() //' Testing'
' Testing '.trimEnd() //' Testing'
'Testing '.trimEnd() //'Testing'

Symbol.prototype.description.

Теперь вы можете получить описание символа, доступа к его Описание недвижимость вместо того, чтобы использовать TOSTRING () Метод:

const testSymbol = Symbol('Test')
testSymbol.description // 'Test'

Улучшения JSON

Перед этим изменением сепаратор линии (\ U2028) и символы сепаратора абзаца (\ U2029) не были разрешены в строках, анализируемых как json.

Использование JSON.PARSE (), эти персонажи привели к SyntaxError Но теперь они разбираются правильно, как определено стандартом JSON.

Хорошо сформированные json.stringify ()

Исправляет Json.stringify () Вывод, когда это обрабатывает суррогатные точки кода UTF-8 (U + D800 до U + DFFF).

До этого изменения звонят Json.stringify () вернет нерабочевший символ Unicode (A «�»).

Теперь эти суррогатные кодовые точки могут быть безопасно представлены в виде строк, использующих Json.stringify () и преобразуется обратно в исходное представление, используя Json.parse () Отказ

Функция. Прототип.

Функции всегда имели метод экземпляра под названием TOSTRING () который возвращает строку, содержащую код функции.

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

Если ранее у нас было

function /* this is bar */ bar () {}

Поведение было это:

bar.toString() //'function bar() {}

Теперь новое поведение:

bar.toString(); // 'function /* this is bar */ bar () {}'

Надеждая, я надеюсь, что эта статья помогла вам догнать некоторые из последних добавок JavaScript, а новые функции мы увидим в 2019 году.

Нажмите здесь, чтобы получить PDF/EPUB/MOBI версию этого поста для чтения в автономном режиме

Флавио