Содержание
- 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=1let result = a ?? bprint(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)
объединяет два или более
объекта в один. Он изменяет целевой объект на месте, поэтому, если
вы предпочитаете создать новый объект, передайте пустой литерал
объекта в качестве первого аргумента.В качестве альтернативы вы можете использовать spread оператор
...
для объединения нескольких объектов: {...
obj1, ... obj2}
, хотя имейте в виду, что spread
не будет вызывать сеттеры для объекта, поэтому, чтобы быть наиболее
переносимым, рассмотрите Object.assign
. Spread
оператор также можно использовать с массивами, как показано в
последнем примере кода.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.stateprint("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 linestring`print(x)x = `1+1=${1+1}`print(x)
Proxy
Прокси-сервер позволяет вам перехватывать вызовы get/set другого объекта. Это может быть полезно для отслеживания изменений свойства, последующего обновления DOM или создания инновационных API, таких как прокси www ниже.
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