? Полное руководство теперь доступно на Amazon

let , const и блокировать обзор let позволяет вам создавать объявления, которые связаны с любым блоком, называемым Block Scoping. Вместо использования var , который обеспечивает объем функций, рекомендуется использовать переменные с аферолом блоков ( let или const ) в ES6.
var a = 2 ;
{
let a = 3 ;
console . log ( a ) ; // 3
let a = 5 ; // TypeError: Identifier 'a' has already been declared
}
console . log ( a ) ; // 2 Другая форма объявления с блоками-это const , которая создает константы. В ES6 const представляет собой постоянную ссылку на значение. Другими словами, содержание Object и Array может измениться, предотвращается только повторное распределение переменной. Вот простой пример:
{
const b = 5 ;
b = 10 ; // TypeError: Assignment to constant variable
const arr = [ 5 , 6 ] ;
arr . push ( 7 ) ;
console . log ( arr ) ; // [5,6,7]
arr = 10 ; // TypeError: Assignment to constant variable
arr [ 0 ] = 3 ; // value is mutable
console . log ( arr ) ; // [3,6,7]
}Несколько вещей, которые нужно помнить:
let и const варьируется от традиционного поднятия переменных и функций. Оба let и const подняты, но не могут быть доступны до их объявления из -за временной мертвой зоныlet и const подходят к ближайшему блоку ограждения.const PI = 3.14 )const должен быть определен с его объявлением.const up let , если вы не планируете повторное согласование переменной. Функции стрел-это короткая рука для написания функций в ES6. Определение функции стрелки состоит из списка параметров ( ... ) , за которым следует маркер => и корпус функции. Для функций с одним аргументом в скобках могут быть опущены.
// Classical Function Expression
function addition ( a , b ) {
return a + b ;
} ;
// Implementation with arrow function
const addition = ( a , b ) => a + b ;
// With single argument, no parentheses required
const add5 = a => 5 + a ; Обратите внимание, что в приведенном выше примере функция стрелки addition реализована с помощью «Краткого тела», которое не требует явного оператора возврата. Обратите внимание на опущенную { } после => .
Вот пример с обычным «корпусом блока». В том числе кудрявые обертки.
const arr = [ 'apple' , 'banana' , 'orange' ] ;
const breakfast = arr . map ( fruit => {
return fruit + 's' ;
} ) ;
console . log ( breakfast ) ; // ['apples', 'bananas', 'oranges']Вот! Есть еще ...
Функции стрелки не просто делают код короче. Они тесно связаны с this обязательным поведением.
Стрелка функционирует с this ключевым словом, отличается от нормальных функций. Каждая функция в JavaScript определяет свой собственный this контекст, но функции стрелки отражают this значение ближайшего контекста окружения. Проверьте следующий код:
function Person ( ) {
// The Person() constructor defines `this` as an instance of itself.
this . age = 0 ;
setInterval ( function growUp ( ) {
// In non-strict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this . age ++ ;
} , 1000 ) ;
}
var p = new Person ( ) ; В Ecmascript 3/5 эта проблема была исправлена путем назначения значения в this переменной, которая может быть закрыта.
function Person ( ) {
const self = this ;
self . age = 0 ;
setInterval ( function growUp ( ) {
// The callback refers to the `self` variable of which
// the value is the expected object.
self . age ++ ;
} , 1000 ) ;
}Как упомянуто выше, функции стрелки отражают это значение ближайшего контекста окружения, поэтому следующий код работает, как и ожидалось, даже с вложенными функциями стрел.
function Person ( ) {
this . age = 0 ;
setInterval ( ( ) => {
setTimeout ( ( ) => {
this . age ++ ; // `this` properly refers to the person object
} , 1000 ) ;
} , 1000 ) ;
}
let p = new Person ( ) ;Узнайте больше о «Лексическом этом» в функциях стрелки здесь
ES6 позволяет устанавливать параметры по умолчанию в определениях функций. Вот простая иллюстрация.
const getFinalPrice = ( price , tax = 0.7 ) => price + price * tax ;
getFinalPrice ( 500 ) ; // 850 ... Оператор называется оператором спреды или отдыха, в зависимости от того, как и где он используется.
При использовании с любым итерационным, он действует, чтобы «распространять» его в отдельные элементы:
const makeToast = ( breadType , topping1 , topping2 ) => {
return `I had ${ breadType } toast with ${ topping1 } and ${ topping2 } ` ;
} ; const ingredients = [ 'wheat' , 'butter' , 'jam' ] ;
makeToast ( ... ingredients ) ;
// "I had wheat toast with butter and jam"
makeToast ( ... [ 'sourdough' , 'avocado' , 'kale' ] ) ;
// "I had sourdough toast with avocado and kale"Распространение также отлично подходит для формирования нового объекта из других объектов:
const defaults = { avatar : 'placeholder.jpg' , active : false }
const userData = { username : 'foo' , avatar : 'bar.jpg' }
console . log ( { created : '2017-12-31' , ... defaults , ... userData } )
// {created: "2017-12-31", avatar: "bar.jpg", active: false, username: "foo"}Новые массивы также могут быть выражены в форме:
const arr1 = [ 1 , 2 , 3 ] ;
const arr2 = [ 7 , 8 , 9 ] ;
console . log ( [ ... arr1 , 4 , 5 , 6 , ... arr2 ] ) // [1, 2, 3, 4, 5, 6, 7, 8, 9] Другое распространенное использование ... собирает все аргументы вместе в массив. Это называется оператором «отдыха».
function foo ( ... args ) {
console . log ( args ) ;
}
foo ( 1 , 2 , 3 , 4 , 5 ) ; // [1, 2, 3, 4, 5]ES6 позволяет объявлять объектные литералы, предоставляя ограниченный синтаксис для инициализации свойств из переменных и определения методов функции. Это также позволяет иметь возможность вычислять клавиши свойств в буквальном определении объекта.
function getCar ( make , model , value ) {
return {
// with property value shorthand
// syntax, you can omit the property
// value if key matches variable
// name
make , // same as make: make
model , // same as model: model
value , // same as value: value
// computed values now work with
// object literals
[ 'make' + make ] : true ,
// Method definition shorthand syntax
// omits `function` keyword & colon
depreciate ( ) {
this . value -= 2500 ;
}
} ;
}
let car = getCar ( 'Kia' , 'Sorento' , 40000 ) ;
console . log ( car ) ;
// {
// make: 'Kia',
// model:'Sorento',
// value: 40000,
// makeKia: true,
// depreciate: function()
// } ES6 обладает новой поддержкой восьми и бинарных литералов. Подготовка числа с 0o или 0O преобразует его в восьмиурочное значение. Посмотрите на следующий код:
let oValue = 0o10 ;
console . log ( oValue ) ; // 8
let bValue = 0b10 ; // 0b or 0B for binary
console . log ( bValue ) ; // 2Разрушение помогает избежать потребности в временных переменных при работе с объектами и массивами.
function foo ( ) {
return [ 1 , 2 , 3 ] ;
}
let arr = foo ( ) ; // [1,2,3]
let [ a , b , c ] = foo ( ) ;
console . log ( a , b , c ) ; // 1 2 3 function getCar ( ) {
return {
make : 'Tesla' ,
model : 'g95' ,
metadata : {
vin : '123abc' ,
miles : '12000'
}
} ;
}
const { make , model } = getCar ( ) ;
console . log ( make , model ) ; // Tesla g95
const { make , metadata : { miles } } = getCar ( ) ;
console . log ( make , miles ) ; // Tesla 12000
ES6 позволяет использовать super метод в (бесклассовых) объектах с прототипами. Ниже приведен простой пример:
const parent = {
foo ( ) {
console . log ( "Hello from the Parent" ) ;
}
}
const child = {
foo ( ) {
super . foo ( ) ;
console . log ( "Hello from the Child" ) ;
}
}
Object . setPrototypeOf ( child , parent ) ;
child . foo ( ) ; // Hello from the Parent
// Hello from the ChildES6 представляет более простой способ добавления интерполяций, которые оцениваются автоматически.
`${ ... }` используется для рендеринга переменных.` Backtick используется в качестве разделителя. let user = 'Kevin' ;
console . log ( `Hi ${ user } !` ) ; // Hi Kevin!for...of итерат над итерационными объектами, такими как массив. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname of nicknames ) {
console . log ( nickname ) ;
}
// di
// boo
// punkeyefor...in итерациях над всеми перечисленными свойствами объекта. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname in nicknames ) {
console . log ( nickname ) ;
}
// 0
// 1
// 2
// size ES6 вводит новый набор структур данных, называемых Map и WeakMap . Теперь мы фактически используем карты в JavaScript все время. На самом деле каждый объект может рассматриваться как Map .
Объект изготовлен из ключей (всегда строк) и значений, тогда как в Map любое значение (как объекты, так и примитивные значения) могут использоваться в качестве ключа или значения. Посмотрите на этот кусок кода:
const myMap = new Map ( ) ;
const keyString = "a string" ,
keyObj = { } ,
keyFunc = ( ) => { } ;
// setting the values
myMap . set ( keyString , "value associated with 'a string'" ) ;
myMap . set ( keyObj , "value associated with keyObj" ) ;
myMap . set ( keyFunc , "value associated with keyFunc" ) ;
myMap . size ; // 3
// getting the values
myMap . get ( keyString ) ; // "value associated with 'a string'"
myMap . get ( keyObj ) ; // "value associated with keyObj"
myMap . get ( keyFunc ) ; // "value associated with keyFunc"Слабая карта
WeakMap -это карта, на которой ключи слабо ссылаются, которая не предотвращает, как его клавиши собирают мусор. Это означает, что вам не нужно беспокоиться о утечках памяти.
Еще одна вещь, которую следует отметить здесь- в WeakMap а не Map каждая клавиша должна быть объектом .
WeakMap имеет только четыре метода delete(key) , has(key) , get(key) и set(key, value) .
const w = new WeakMap ( ) ;
w . set ( 'a' , 'b' ) ;
// Uncaught TypeError: Invalid value used as weak map key
const o1 = { } ,
o2 = ( ) => { } ,
o3 = window ;
w . set ( o1 , 37 ) ;
w . set ( o2 , "azerty" ) ;
w . set ( o3 , undefined ) ;
w . get ( o3 ) ; // undefined, because that is the set value
w . has ( o1 ) ; // true
w . delete ( o1 ) ;
w . has ( o1 ) ; // falseУстановленные объекты - это коллекции уникальных значений. Дублирующие значения игнорируются, так как коллекция должна иметь все уникальные значения. Значения могут быть примитивными типами или ссылками на объекты.
const mySet = new Set ( [ 1 , 1 , 2 , 2 , 3 , 3 ] ) ;
mySet . size ; // 3
mySet . has ( 1 ) ; // true
mySet . add ( 'strings' ) ;
mySet . add ( { a : 1 , b : 2 } ) ; Вы можете итерации по набору по порядку вставки, используя либо метод forEach , либо for...of цикла.
mySet . forEach ( ( item ) => {
console . log ( item ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} ) ;
for ( let value of mySet ) {
console . log ( value ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} Наборы также имеют методы delete() и clear() .
Слабый набор
Подобно WeakMap , объект WeakSet позволяет вам хранить слабо удерживаемые объекты в коллекции. Объект в WeakSet происходит только один раз; Это уникально в коллекции слабых.
const ws = new WeakSet ( ) ;
const obj = { } ;
const foo = { } ;
ws . add ( window ) ;
ws . add ( obj ) ;
ws . has ( window ) ; // true
ws . has ( foo ) ; // false, foo has not been added to the set
ws . delete ( window ) ; // removes window from the set
ws . has ( window ) ; // false, window has been removedES6 представляет новый класс синтаксис. Здесь следует отметить, что класс ES6 не является новой объектно-ориентированной моделью наследования. Они просто служат синтаксическим сахаром по сравнению с существующим прототипом наследования JavaScript.
Один из способов посмотреть на класс в ES6 - это всего лишь новый синтаксис для работы с прототипами и функциями конструктора, которые мы использовали бы в ES5.
Функции, определяемые с использованием static ключевого слова, реализация функций Static/Class в классе.
class Task {
constructor ( ) {
console . log ( "task instantiated!" ) ;
}
showId ( ) {
console . log ( 23 ) ;
}
static loadAll ( ) {
console . log ( "Loading all tasks.." ) ;
}
}
console . log ( typeof Task ) ; // function
const task = new Task ( ) ; // "task instantiated!"
task . showId ( ) ; // 23
Task . loadAll ( ) ; // "Loading all tasks.."расширяется и супер в классах
Рассмотрим следующий код:
class Car {
constructor ( ) {
console . log ( "Creating a new car" ) ;
}
}
class Porsche extends Car {
constructor ( ) {
super ( ) ;
console . log ( "Creating Porsche" ) ;
}
}
let c = new Porsche ( ) ;
// Creating a new car
// Creating Porsche extends позволяет ребенку унаследовать от родительского класса в ES6. Важно отметить, что полученный конструктор должен назвать super() .
Кроме того, вы можете вызвать метод класса родительского класса в методах детского класса с использованием super.parentMethodName()
Узнайте больше о классах здесь
Несколько вещей, которые нужно помнить:
function при определении функций внутри определения класса. Symbol - это уникальный и неизменный тип данных, представленный в ES6. Цель символа - генерировать уникальный идентификатор, но вы никогда не сможете получить никакого доступа к этому идентификатору.
Вот как вы создаете символ:
const sym = Symbol ( "some optional description" ) ;
console . log ( typeof sym ) ; // symbol Обратите внимание, что вы не можете использовать new с Symbol(…) .
Если символ используется в качестве свойства/ключа объекта, он хранится особым образом, что свойство не будет отображаться в обычном перечислении свойств объекта.
const o = {
val : 10 ,
[ Symbol ( "random" ) ] : "I'm a symbol" ,
} ;
console . log ( Object . getOwnPropertyNames ( o ) ) ; // val Чтобы получить свойства символа объекта, используйте Object.getOwnPropertySymbols(o)
Итератор обращается к элементам из коллекции по одному, одновременно отслеживая свою текущую позицию в этой последовательности. Он предоставляет метод next() , который возвращает следующий элемент в последовательности. Этот метод возвращает объект с двумя свойствами: выполнено и значением.
ES6 имеет Symbol.iterator , который определяет итератор по умолчанию для объекта. Всякий раз, когда объект должен быть итерацией (например, в начале a for ... of Loop), его метод @@ iterator вызывается без аргументов, и возвращаемый итератор используется для получения значений для итерации.
Давайте посмотрим на массив, который является итерабильным, и итератором, который он может создать для потребления своих значений:
const arr = [ 11 , 12 , 13 ] ;
const itr = arr [ Symbol . iterator ] ( ) ;
itr . next ( ) ; // { value: 11, done: false }
itr . next ( ) ; // { value: 12, done: false }
itr . next ( ) ; // { value: 13, done: false }
itr . next ( ) ; // { value: undefined, done: true } Обратите внимание, что вы можете написать пользовательские итераторы, определяя obj[Symbol.iterator]() с определением объекта.
Функции генератора - это новая функция в ES6, которая позволяет функции генерировать много значений с течением времени, возвращая объект, который может быть итерация, чтобы вытащить значения из функции по одному значению за раз.
Функция генератора возвращает итерабильный объект , когда он вызывается. Он написан с использованием нового * синтаксиса, а также нового ключевого слова yield , представленного в ES6.
function * infiniteNumbers ( ) {
let n = 1 ;
while ( true ) {
yield n ++ ;
}
}
const numbers = infiniteNumbers ( ) ; // returns an iterable object
numbers . next ( ) ; // { value: 1, done: false }
numbers . next ( ) ; // { value: 2, done: false }
numbers . next ( ) ; // { value: 3, done: false }Каждый раз, когда выходит выход , выходное значение становится следующим значением в последовательности.
Кроме того, обратите внимание, что генераторы вычисляют свои данные значения по требованию, что позволяет им эффективно представлять последовательности, которые являются дорогостоящими для вычисления или даже бесконечных последовательностей.
ES6 имеет собственную поддержку обещаний. Обещание - это объект, который ожидает завершения асинхронной операции, и когда эта операция завершается, обещание либо выполнено (разрешено), либо отклоняется.
Стандартным способом создания обещания является использование new Promise() , который принимает обработчик, которому дают две функции в качестве параметров. Первый обработчик (обычно называемый resolve ) - это функция для вызова будущего значения, когда он будет готов; А второй обработчик (обычно называемый reject ) - это функция, чтобы вызвать обещание, если оно не может разрешить будущее значение.
const p = new Promise ( ( resolve , reject ) => {
if ( /* condition */ ) {
resolve ( /* value */ ) ; // fulfilled successfully
} else {
reject ( /* reason */ ) ; // error, rejected
}
} ) ; Каждое обещание имеет метод, названный then , который берет пару обратных вызовов. Первый обратный вызов вызывается, если обещание разрешено, а второе называется, если обещание отклоняется.
p . then ( ( val ) => console . log ( "Promise Resolved" , val ) ,
( err ) => console . log ( "Promise Rejected" , err ) ) ; Возвращение значения от then обратные вызовы передадут значение следующему then обратный вызов.
const hello = new Promise ( ( resolve , reject ) => { resolve ( "Hello" ) } ) ;
hello . then ( ( str ) => ` ${ str } World` )
. then ( ( str ) => ` ${ str } !` )
. then ( ( str ) => console . log ( str ) ) // Hello World!При возврате обещания разрешенная ценность обещания будет передана следующему обратному обращению, чтобы эффективно скрепить их вместе. Это простая техника, чтобы избежать «ада обратного вызова».
const p = new Promise ( ( resolve , reject ) => { resolve ( 1 ) } ) ;
const eventuallyAdd1 = ( val ) => new Promise ( ( resolve , reject ) => { resolve ( val + 1 ) } ) ;
p . then ( eventuallyAdd1 )
. then ( eventuallyAdd1 )
. then ( ( val ) => console . log ( val ) ) ; // 3