Современный Javascript: всё, что вы пропустили за последние 10 лет

от автора

JavaScript прошел долгий путь с тех пор, как я знал его как букву «D» в DHTML. Для всех, кто, как я, не хотел использовать новейший синтаксис, который может потребовать полифиллов или транспилятора, я написал эту шпаргалку, чтобы вы познакомились со всеми достоинствами, которые широко поддерживаются в современных браузерах.

Содержание

  • Array functions
  • const/let
  • Nullish coalescing ?? and Optional chaining?.. operators
  • Async/Await
  • Arrow functions ()=>{}
  • for…of
  • for await…of
  • Classes
  • get/set
  • function default parameters
  • function named parameters
  • function rest… parameter
  • Destructuring
  • Shorthand functions aka Methods
  • Promise.all
  • Template literals
  • Proxy
  • Module import/export
  • Читать ещё

(Исправления по качеству перевода, пожалуйста, присылайте в личку)

Array functions

Ознакомьтесь со всеми этими новыми нативными функциями массива. Больше нет необходимости в underscore или lodash.

Array.every()
Array.filter()
Array.find()
Array.findIndex()
Array.forEach()
Array.from()
Array.includes()
Array.isArray()
Array.lastIndexOf()
Array.map()
Array.reduce()
Array.reduceRight()
Array.some()

Array docs

const/let

Эти новые ключевые слова объявляют переменные в области видимости блока (в отличие от глобальной или функциональной области). Использование const подразумевает, что значение не изменится, поскольку ссылка неизменна. Используйте let, если значение изменится.

Let documentation

?? и ?.

?? проверяет, является ли значение нулевым или неопределенным. Больше не нужно использовать !!.

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

Optional chaining documentation

let a, b=1 let result = a ?? b print(result)  result = (a !== null && a !== undefined) ? a : b; print(result)        print({x:1}?.a?.b ?? "not found")       

Async/Await

Ключевые слова async/await нужны, чтобы спасти вас от ада обратных вызовов. Используйте await, чтобы сделать асинхронный вызов похожим на синхронный вызов, т.е. выполнение await fetchUserName() не перейдет к следующей строке, пока fetchUserName() не будет завершен. Обратите внимание: чтобы использовать await, вы должны выполнять функцию, объявленную как async, т.е. async function fn () {await fetchUserName ()}.

Async/Await docs.

function fetchUserName() {   return new Promise(resolve => setTimeout(resolve, 500)) }        async function withAsync() {   print("withAsync: fetching...")   await fetchUserName()   print("withAsync: done") } await withAsync()        function withoutAsync() {   print("withoutAsync: fetching...")   fetchUserName().then(()=>print("withoutAsync done")) } withoutAsync()     

Arrow functions ()=>{}

Это функции, привязанные к текущему контексту. Есть три основных вида, которые вы увидите в дикой природе:
один аргумент, одна строка, много строк.

Форма с одним аргументом не требует скобок, а форма с одной строкой не требует оператора return; возврат безоговорочный.

1 const fn = a => a*2

Один аргумент. Одна линия.

Многострочная форма требует оператора return, если функция намеревается что-то вернуть. Для нескольких аргументов требуются круглые скобки.

const fn = (a,b) => {   console.log(a,b)   return a*b }

Несколько аргументов, несколько строк.

Arrow function docs

for…of

Используется для перебора итератора. Аналогично for...in, за исключением того, что вам не нужно проверять hasOwnProperty. Вы не можете использовать этот синтаксис цикла для объекта напрямую, потому что у объекта нет итератора. Вместо этого используйте Object.entries ({}) для получения итерации.

for…of docs

const x = {a: 1, b: 2} for (const [key, value] of Object.entries(x)) {   print(`${key}=${value}`) }

for await…of

Асинхронная итерация была представлена ​​в 2018 году. Как и Promise.all, ее можно использовать для синхронизации многих асинхронных задач. В приведенном ниже примере показаны 3 задачи, выполняющиеся асинхронно. Цикл обрабатывает один результат за раз по порядку; в этом случае самые быстрые задачи для выполнения очевидны только в конце итерации.

for await…of docs

const delay = (n) => {   return new Promise((resolve) => {     setTimeout(()=>{       print("resolve "+n)       resolve(n)     }, n)   }) }  const delays = [   delay(150),   delay(50),   delay(25) ]  for await (const ret of delays) {   print("for loop await "+ret) }

Classes

В 2015 году ES6 перенес классы в Javascript. Классы Javascript похожи на классы из других языков, которые вы знаете и любите. Наследование, методы класса, геттеры и сеттеры, свойства и т.д.

Class documentation

class A {   constructor(name) {     this.name = name   }   myProp = "myProp"   static foo() {     print("Static method says foo")   } } class B extends A {   constructor(name, age) {     super(name)     this.age = age   }   toString() {     return `${this.name} ${this.age}`   } } A.foo() const b = new B("Catch", 22) print(b) print(b.myProp)

get/set

Get и set — это функции, которые называются свойствами, например person.age = 16; person.age> 18. Это очень удобно, когда вам нужно динамическое или вычисляемое свойство. И их можно использовать как с классами, так и с обычными объектами.

get/set documentation

Classes with getters and setters

class A {   constructor() {     this._firstName = "Jane"     this._lastName = "Smith"   }   get fullName() {     return `${this._firstName} ${this._lastName}`   }   set firstName(v) {     this._firstName = v   } } const a = new A() print(a.fullName) a.firstName = "John" print(a.fullName)

Objects with getters and setters

const x = {   get now() { return new Date() } } print(x.now)

function default parameters

Ура! Теперь вы можете указать параметры по умолчанию в определении вашей функции. Работает, как и следовало ожидать.

Default parameter docs

function greet(msg="Hello world") {   print(msg) } greet() greet("hi")

function named parameters

С помощью магии разрушения объектов функции теперь могут иметь именованные параметры.

Named parameter docs

function greet({name = "Jane", age = 42} = {}){   print(name + " " +age) } greet() greet({name: "John", age: 21})

function rest… parameter

Параметр сброса позволяет функции принимать произвольное количество аргументов в виде массива. Рекомендуется использовать это вместо arguments.

Rest parameter docs

function greet(msg1, ...msgs) {   print(msg1)   msgs.forEach(s => print(s)) } greet("hi", "hello", "world")

Object.assign and spread operator

Object.assign(target, source) объединяет два или более объекта в один. Он изменяет целевой объект на месте, поэтому, если вы предпочитаете создать новый объект, передайте пустой литерал объекта в качестве первого аргумента.

В качестве альтернативы вы можете использовать оператор распространения ... для объединения нескольких объектов: {... obj1, ... obj2}, хотя имейте в виду, что spread не будет вызывать сеттеры для объекта, поэтому, чтобы быть наиболее переносимым, рассмотрите Object.assign. Оператор распространения также можно использовать с массивами, как показано в последнем примере кода.

Spread syntax docs

const source = {x: 1, y: 4} const target = Object.assign({}, source) print(JSON.stringify(target))  const spread = {a: 1, b: 2, ...source} print(JSON.stringify(spread))  const ary1 = [1] const ary = [...ary1, [2,3]] print(ary)       

Destructuring

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

Destructuring docs и MDN docs

function f() {   return [1, 2]; } let [a, b] = f() print("a="+a + " b=" + b)  const obj = {state: {id: 1, is_verified: false}} const {id, is_verified: verified} = obj.state print("id = " + id) print("verified = " + verified)  for (const [key, value] of Object.entries({a: 1, b: 2, c: 3})) {   print(key + " is " + value); }       

Shorthand functions aka Methods

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

Две функции (fn1, fn2) эквивалентны в примере ниже.

Method guide

const x = {   type: "x",   shorthand() {     print("shorthand "+this.type)   },   long: function() {     print("long "+this.type)   } } x.shorthand() x.long() 

Promise.all

Я в основном пропускал promises, потому что async/await предпочтительнее, но иногда вам нужно синхронизировать несколько асинхронных вызовов, и Promise.all — самый простой способ сделать это.

Promise.all documentation

const delay = (n) => {   return new Promise((resolve) => {     setTimeout(()=> resolve(n), n)   }) } async function main() {   const delays = [100, 200, 300].map(n => delay(n))   print("waiting…")   const res = await Promise.all(delays)   print("done. result is " + res) } main()       

Template literals

Этот новый синтаксис, также известный как template strings, обеспечивает простую интерполяцию строк и «многострочные строки» (multi-line strings).

Template literal docs

let x = `multi       line string` print(x)  x = `1+1=${1+1}` print(x)

Proxy

Прокси-сервер позволяет вам перехватывать вызовы get/set другого объекта. Это может быть полезно для отслеживания изменений свойства, последующего обновления DOM или создания инновационных API, таких как прокси www ниже.

image

Proxy docs

let _nums = [1,2,3] let nums = new Proxy(_nums, {   set(target, key, value) {     target[key] = value     print("set called with " + key + "=" + value)     print("update DOM")     return true   } }) nums.push(4) print("nums: " + nums) print("_nums: " + _nums)

Module import/export

Модули позволяют вам создавать пространство имен для вашего кода и разбивать функциональные возможности на файлы меньшего размера. В приведенном ниже примере у нас есть модуль с именем greet.js, который включается в index.html. Обратите внимание: загрузка модуля всегда откладывается, поэтому он не блокирует рендеринг HTML. Есть много способов импортировать / экспортировать функциональность из файлов js, подробнее читайте в документации по экспорту.

Import docs

function greet(msg) {   console.log("greet:", msg) } export default greet

Файл с именем «greet.js» в каталоге "/js".

<script type="module">   import greet from "/js/greet.js"   greet("hi") </script>

index.html

Читать ещё

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

References

Guides

ссылка на оригинал статьи https://habr.com/ru/post/557634/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *