Содержание
- 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)
объединяет два или более объекта в один. Он изменяет целевой объект на месте, поэтому, если вы предпочитаете создать новый объект, передайте пустой литерал объекта в качестве первого аргумента.В качестве альтернативы вы можете использовать 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.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 ниже.
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
yarkov
Больше нет необходимости в
подчеркиванииили lodash
Гугл транслейт перевёл underscore так?