JS 3
Class
new.target - ссылается либо на функцию-конструктор, либо выдает undefined
const name = processor
const xProperty = Symbol('x')
class Point {
  counstructor(x, y) {
    this.x = x
    this.y = y
  }
  static TEST() {
    console.log(123)
  }
  static TEST2 = 1; // НЕЛЬЗЯ!!!
  static get zero() {
    return new Point(0, 0)
  }
  toString() {
    return `${this.x}, ${this.y}`
  }
  get x() {
    return this[xProperty]
  }
  set x(value) {
    this[xProperty] = value
  }
  [name]() {
    console.log('Im alive')
  }
}
// Point.zero = new Point(0,0) // МОЖНО
Классы не хойстятся
typeof выдаст function
Нельзя вызывать без new
Можно делать класс expression
Методы класса имеют ссылку на то, где созданы  
class Rectangle {
  constructor(x, y, width, height) {
    this.x = x
    this.y = y
    this.width = width
    this.height = height
  }
  * [Symbol.iterator]() {
    yield {x: this.x, y: this.y}
    yield {x: this.x + this.width, y: this.y}
    yield {x: this.x + this.width, y: this.y + this.height}
    yield {x: this.x, y: this.y + this.height}
  }
}
const rect = new Rectangle(3, 3, 100, 100)
for (let point of rect) {
  console.log(point)
}
class FilledRectangle extends Rectangle {
  constructor(x, y, width, height, color) {
    super(x, y, width, height)
    this.color = color
  }
}
const colorRect = new FilledRectangle(2, 2, 100, 100, 'red')
class Stack extends Array {
  get top() {
    return this[this.length - 1]
  }
  get length() {
    return 5 // невозможно переопределить
  }
  push(...args) {
    console.log('Pushing!')
    super.push(...args)
  }
}
| writable | enumerable | configurable | |
|---|---|---|---|
| C.prototype | x | x | x | 
| C.prototype.constructor | x | x | v | 
| C.foo (static) | v | x | v | 
| C.prototype.foo | v | x | v | 
Можно экстендить от null
class Rectangle extends null {
  constructor(x, y, width, height) {
    return {x, y, width, height}
  }
}
Создание инстансов
es5 c1 - c2 - c3
es6 c3 - c2 - c1  
Если экстендим от Object (то именно в нем создается инстанс)
Прототипом класса является function
Rectangle.__proto__ // function
Rectangle extends Object
Rectangle.__proto__ // object
Встроенные типы (Array например) игнорируют this. Называются экзотическими объектами.
Symbol.species
прочитать Переопределяет конструктор, который будет использоваться встроенными методами языка, при создании объекта
Promise
let x = new Promise((res, rej) => {
  setTimeout(() => {
      if (Math.random() < .5) {
        res('Fine')
      } else {
        rej('Bad')
      }
  }, 1000)
})
x
  .then((data) => {console.log('ok', data)}, (data) => {console.log('error', data)})
  .then((data) => {console.log('ok2', data)}, (data) => {console.log('error2', data)})
.catch - сокращенный синтаксис записи then без первого аргумента
Promise.reject() - создает проваленный промис
Если в цепочке промисов поймали ошибку и не отправили ее дальше, то считается, что ошибка обработана
Если из промиса возвращаем другой промис, то в следующий then придет не объект, а подождет пока завершится и получит результат работы   
fetch('http://jsonplaceholder.typicode.com/users')
  .then(r => r.json())
  .then(data => console.log(data))
fetch('http://jsonplaceholder.typicode.com/users')
  .then(r => r.json())
  .then(data => fetch(`http://jsonplaceholder.typicode.com/users/${data[0].id}`))
  .then(r => json())
  .then(data => console.log(data))
Promise.all([
  fetch...,
  data
])
  .then(obj => Promise.all([obj[0].json(), obj[1]]))
  .then(data => console.log(data))