Подводя итог тому, что я узнал из курса, и, надеюсь, это будет полезно для начинающих, изучающих ES6.

Ранее я сразу погрузился в изучение и использование React, не имея хорошего понимания Javascript и ES6.

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

Еще одна ошибка заключалась в том, чтобы изучать React вместе с Redux, хороший пост о том, как изучать экосистему React. https://github.com/petehunt/react-howto

Вдохновленный https://medium.com/craft-academy/everything-i-learned-from-es6-for-everyone-ff93ebc64b86 и столкнувшись со многими проблемами в React, я решил пройти курс, чтобы полностью понять ES6. .

Объявление переменной

В ES6 появились переменные блочной области видимости, такие как let и const.

let работает аналогично var , но объявляемая им переменная имеет область действия блока и существует только в текущем блоке.

function order(x, y) {
    if (x > y) {
        let tmp = x; // the tmp variable only exist within the if
        x = y;
        y = tmp;
    }
    console.log(tmp===x); // ReferenceError: tmp is not defined
    return [x, y];
}

const работает так же, как let, но объявленная переменная должна быть немедленно инициализирована со значением, которое нельзя изменить впоследствии.

const foo;
    // SyntaxError: missing = in const declaration

const bar = 123;
bar = 456;
    // TypeError: `bar` is read-only

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

Это более краткий синтаксис для написания функциональных выражений. Они используют новый токен =>, который выглядит как толстая стрелка.

  1. Стрелочные функции не связывают собственный this, что означает, что this в стрелочных функциях ссылается на родительский лексический объект.
  2. Стрелочные функции допускают неявный возврат (возврат значений без ввода return ).
var phraseSplitterEs5 = function phraseSplitter(phrase) { 
    return phrase.split(' '); 
};   //ES5 
 
const phraseSplitterEs6 = phrase => phrase.split(" "); 
  //ES6 with implicit return
console.log(phraseSplitterEs6("ES6 Awesomeness"));  // ["ES6", "Awesomeness"]

Литералы шаблонов

С литералами шаблонов ES6 упрощает объединение строк с переменными JS.

var a = 5;
var b = 10;
//ES5
console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
//ES6
console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`);

Разрушение

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

let a, b, rest;
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({a, b} = {a: 10, b: 20});
console.log(a); // 10
console.log(b); // 20

Замена переменных методом деструктуризации

var a = 1;
var b = 3;
//ES5
var tmp = a;
a = b;
b = tmp;
//ES6
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

Аргументы функции деструктурирования

//ES5
function myFunc(opts) {
  var name = opts.name;
  var age = opts.age;
}

myFunc({ name: 'John', age: 25 });
//ES6
function myFunc({name, age}) {
  //do something with name and age
}

Классы

Классы ES6 обеспечивают синтаксический сахар по сравнению с наследованием на основе прототипов JS.

Метод constructor — это специальный метод для создания и инициализации объекта, созданного с помощью class.

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
   get area() {  //getter method
    return this.calcArea();
  } //getter method
  set colorOfShape(color) { 
    this.color = color;
  } //setter method
  calcArea() {
    return this.height * this.width;
  } 
}

Расширить класс

class Square extends Rectangle {
  constructor(height) {
    super(height);
 }

Обещания

Объект Promise относится к конечному завершению (или сбою) асинхронной операции и ее результирующему значению.

new Promise( /* executor */ function(resolve, reject) { ... } );

Исполнитель передается в реализацию Promise с функциями разрешения и отклонения. Функции resolve и reject при вызове разрешают или отклоняют промис соответственно.

Исполнитель обычно инициирует некоторую асинхронную работу, а затем, как только она завершится, либо вызывает функцию resolve для разрешения промиса, либо reject it, если произошла ошибка.

Если в функции-исполнителе возникает ошибка, обещание отклоняется.

Promise находится в одном из следующих состояний:

  • ожидание: исходное состояние, ни выполнено, ни отклонено.
  • выполнено: означает, что операция завершена успешно.
  • отклонено: означает, что операция не удалась.

const p = new Promise((resolve, reject) => {
  const data = ...//perform ajax call 
  if(data) { 
    resolve(data);
  } 
  else { 
    reject(Error('Error, data not found'));
  }
});
p
  .then(data => console.log(data))
  .catch(err => console.error(err))

Генератор

Генераторы — это функции, из которых можно выйти и снова войти позже. Их контекст (привязки переменных) будет сохранен при повторных входах.

Вызов функции генератора не выполняется немедленно; вместо этого возвращается объект итератор. Когда вызывается метод next() итератора, тело функции-генератора выполняется до первого выражения yield, которое указывает значение, которое должно быть возвращено из итератора или, с yield*, делегирует другой функции-генератору.

function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

function* generator(i) {
  yield i;
  yield* anotherGenerator(i);
  yield i + 10;
}

var gen = generator(10);

console.log(gen.next().value); // { value: "10", done: false }
console.log(gen.next().value); // { value: "11", done: false }
console.log(gen.next().value); // { value: "12", done: false }
console.log(gen.next().value); // { value: "13", done: false }
console.log(gen.next().value); // { value: "20", done: true }

Статические и прототипные функции ES6

Статические функции массива ES6

Array.from

Array.from предназначен для преобразования массивных элементов в массивы, примером массивного элемента является NodeList, полученный из document.getElementsByClassName().

const spans = document.querySelectorAll('span.name'); //returns a NodeList object
// for-of only works with iterable values
for (const span of spans) { // TypeError
    console.log(span);
}

const spansArray = Array.from(spans);
for (const spanElement of spansArray) { // OK, iterable
    console.log(spanElement);
}

Массив.из

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

Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Функции прототипа массива ES6

Массив.прототип.найти()

Array.prototype.find(callback[, thisArg])

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

  1. Элемент: текущий обрабатываемый элемент в массиве.
  2. Индекс : индекс текущего обрабатываемого элемента в массиве.
  3. Массив: массив, на котором будет выполняться функция.
function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5

Массив.прототип.findIndex()

arr.findIndex(callback[, thisArg])

Метод findIndex аналогичен методу find массива. Он принимает обратный вызов в качестве аргумента и возвращает индекс первого элемента в массиве, который удовлетворяет предоставленной функции тестирования.

function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2

Массив.прототип.заполнить()

Метод fill заполняет все элементы массива от начального индекса до конечного индекса статическим значением.

arr.fill(value, start, end)
  1. Значение: значение для поиска массива
  2. Начало: начальный индекс, необязательно, по умолчанию 0
  3. Конец: конечный индекс, необязательный, по умолчанию равен длине массива

Прокси

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

let proxy = new Proxy(target, trap);

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

Одним из популярных вариантов использования прокси-сервера является правильное форматирование данных, которые устанавливаются в объекте. Пример, который привел Уэс, заключался в исправлении формата телефонных номеров, установленных в объекте.

//Trap
const phoneHandler = { 
  set(target, name, value) {
    target[name] = value.match(/[0-9]/g).join('');
  }, 
  get(target, name) {
    return target[name].replace(/(\d{3})(\d{3})(\d{4})/,'($1)-$2-$3'
  }
}
//Proxy
const phoneNumbers = new Proxy({}, phoneHandler);
//an empty object for the target 
//Demo
phoneNumbers.work = '(234) 234 2343'; //setting incorrectly
phoneNumber.work
//returns "(234)-234-2343"

Наборы и слабые наборы

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

Набор повторяем благодаря использованию {for…of..} и использованию Set.prototype.forEach.

var mySet = new Set();

mySet.add(1); // Set { 1 }
mySet.add(5); // Set { 1, 5 }
mySet.add(5); // Set { 1, 5 }

Важные API набора:

  1. Set.prototype.add(value): добавление нового значения
  2. Set.prototype.has(value): возвращает логическое значение, если элемент присутствует.
  3. Set.prototype.clear() : удалить все элементы в наборе
  4. Set.prototype.size() : возвращает количество значений в наборе

Слабый набор

WeakSets и Sets очень похожи. Различия между ними заключаются

  1. WeakSets может содержать только объекты
  2. WeakSets не перечислим. В WeakSet нет итератора.
  3. Элементы в WeakSet автоматически удаляются сборщиком мусора.

Карты и слабые карты

Карты похожи на объект, в котором хранятся пары ключ-значение. Карты имеют аналогичный API с наборами.

const dogs = new Map();
dogs.set('Snickers', 3);
dogs.set('Sunny', 2);
dogs.set('Hugo', 10);
dogs.has('Snickers');
//true
dogs.delete('Hugo')
//true 
dogs
//Map("Snickers" => 3, "Sunny" => 2)
dogs.forEach(value => console.log(value));
// 3 "Snickers"
// 2 "Sunny"
for (const [key,value] of dogs) {
  console.log(key,val);
}
//Snickers 3
//Sunny 2

Слабые карты

Слабая карта похожа на то, что слабое множество относится к набору. Слабая карта не имеет размера, она не перечислима и автоматически удаляется сборщиком мусора.

const weakDogs = new WeakMap();
weakDogs.set('weakSnickers', 3);
weakDogs.set('weakSunny', 2);
weakDogs.forEach(value => console.log(value));
//Error a weakMap is not iterable