ES6

JS evolution

Block scope variables

ES5

var x = 'outer';
function test(inner) {
  if (inner) {
    var x = 'inner'; // scope whole function
    return x;
  }
  return x; // gets redefined on line 4
}

test(false); // undefined 
test(true); // inner

ES6

let x = 'outer';
function test(inner) {
  if (inner) {
    let x = 'inner';
    return x;
  }
  return x; // gets result from line 1 as expected
}

test(false); // outer
test(true); // inner

ES5

(function(){
  var private2 = 1;
})();

console.log(private2); // Uncaught ReferenceError

ES6

{
  let private3 = 1;
}

console.log(private3); // Uncaught ReferenceError

IIFE (immediately invoked function expression)

IIFE используется для содержания глобальной среды в чистоте

Достаточно использовать блоки и let

ES6

{
    const ARR = [5, 6];
    ARR.push(7);
    console.log(ARR); // [5,6,7]
    ARR = 10; // TypeError
    ARR[0] = 3; // значение можно менять
    console.log(ARR); // [3,6,7]
}

const

Другой формой объявления переменной с блочной областью видимости является ключевое слово const. Оно предназначено для объявления переменных (констант), значения которых доступны только для чтения. Это означает не то, что значение константы неизменно, а то, что идентификатор переменной не может быть переприсвоен.

О чём стоит помнить:

 

 

  • Когда дело касается поднятия переменных (hoisting) let и const, их поведение отличается от традиционного поведения var и function. И let и const не существуют до своего объявления
  •  
  • Областью видимости let и const является ближайший блок.
  •  
  • В const одновременно с объявлением переменной должно быть присвоено значение.

Стрелочные функции

function Person() {
    var self = this;
    self.age = 0;

    setInterval(function growUp() {
// Коллбэк относится к переменной `self`,
// значением которой является
// ожидаемый объект.
        self.age++;
    }, 1000);
}
function Person() {
    this.age = 0;

    setInterval(() => {
        this.age++; 
// `this` относится к объекту person
    }, 1000);
}

var p = new Person();

ES5

ES6

 Каждая функция в JavaScript определяет свой собственный контекст this

внутри стрелочных функций значение this то же самое, что и снаружи

var _this = this; // need to hold a reference

$('.btn').click(function(event){
  _this.sendData(); // reference outer this
});

$('.input').on('change',function(event){
  this.sendData(); // reference outer this
}.bind(this)); // bind to outer this
// this will reference the outer one
$('.btn').click((event) => 
     this.sendData());

// implicit returns
const ids = [291, 288, 984];
const messages = ids.map(value => 
    `ID is ${value}`);

ES5

ES6

Параметры по умолчанию

let getFinalPrice = (price, tax = 0.7) => price + price * tax;
getFinalPrice(500); // 850, так как значение tax не задано

getFinalPrice(500, 0.2); // 600, значение tax по-умолчанию
                        // заменяется на 0.2

ES5

function point(x, y, isFlag){
  x = x || 0;
  y = y || -1;
  isFlag = isFlag || true;
  console.log(x,y, isFlag);
}

point(0, 0) // 0 -1 true 
point(0, 0, false) // 0 -1 true 
point(1) // 1 -1 true
point() // 0 -1 true

ES6

function point(x = 0, y = -1, isFlag = true){
  console.log(x,y, isFlag);
}

point(0, 0) // 0 0 true
point(0, 0, false) // 0 0 false
point(1) // 1 -1 true
point() // 0 -1 true

Spread / Rest оператор

  • ... Oператор называют как spread или rest, в зависимости от того, как и где он используется.
  • To escape symbol use backslash \

Spread

function foo(x, y, z) {
    console.log(x, y, z);
}

let arr = [1, 2, 3];
foo(...arr); // 1 2 3

Rest

function foo(...args) {
    console.log(args);
}
foo(1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]

Расширение возможностей литералов объекта

function getCar(make, model, value) {
    return {
        // с синтаксисом короткой записи можно пропускать значение свойства, если оно
        // совпадает с именем переменной, значение которой мы хотим использовать
        make,  // аналогично make: make
        model, // аналогично model: model
        value, // аналогично value: value

        // вычисляемые свойства теперь работают в литералах объекта
        ['make' + make]: true,

        // Короткая запись метода объекта пропускает ключевое слово `function` и двоеточие. 
        // Вместо "depreciate: function() {}" можно написать:
        depreciate() {
            this.value -= 2500;
        }
    };
}

let car = getCar('Kia', 'Sorento', 40000);
console.log(car);
// {
//     make: 'Kia',
//     model:'Sorento',
//     value: 40000,
//     makeKia: true,
//     depreciate: function()
// }

Destructuring Assignment

Text

Получение элемента из массива

ES5

var array = [1, 2, 3, 4];

var first = array[0];
var third = array[2];

console.log(first, third); // 1 3

ES6

const array = [1, 2, 3, 4];

const [first, ,third] = array;

console.log(first, third); // 1 3

Обмен значениями

Text

ES5

var a = 1;
var b = 2;

var tmp = a;
a = b;
b = tmp;
console.log(a, b); // 2 1

ES6

let a = 1;
let b = 2;

[a, b] = [b, a];

console.log(a, b); // 2 1

Destructuring Assignment

Text

Деструктуризация нескольких возвращаемых значений

ES5

function margin() {
  var left=1, right=2, 
        top=3, bottom=4;
  return { 
        left: left, 
        right: right,
        top: top, 
        bottom: bottom 
    };
}

var data = margin();
var left = data.left;
var bottom = data.bottom;

console.log(left, bottom); // 1 4

ES6

function margin() {
  const left=1, right=2,
        top=3, bottom=4;

  return { left, right, top, bottom };
}

const { left, bottom } = margin();

console.log(left, bottom); // 1 4

С ES6 вызывающий код выбирает только нужные данные

Destructuring Assignment

Text

Деструктуризация и сопоставление параметров

ES5

var user = {
        firstName: 'Adrian',
        lastName: 'Mejia'};

function getFullName(user) {
  var firstName = user.firstName;
  var lastName = user.lastName;

  return firstName + ' ' + lastName;
}

console.log(getFullName(user)); 
// Adrian Mejia

ES6

const user = {
            firstName: 'Adrian', 
            lastName: 'Mejia'};

function getFullName({ firstName, lastName }) {
  return `${firstName} ${lastName}`;
}

console.log(getFullName(user)); // Adrian Mejia

Destructuring Assignment

Text

Глубокое сопоставление (деструктуризация объекта )

ES5

function settings() {
  return { display: { color: 'red' }, keyboard: { layout: 'querty'} };
}

var tmp = settings();
var displayColor = tmp.display.color;
var keyboardLayout = tmp.keyboard.layout;

console.log(displayColor, keyboardLayout);
 // red querty

ES6

function settings() {
  return { display: { color: 'red' }, keyboard: { layout: 'querty'} };
}

const { display: { color: displayColor }, keyboard: { layout: keyboardLayout }} = settings();

console.log(displayColor, keyboardLayout); // red querty

Destructuring Assignment

Советы:

 

  • Используйте деструктуризацию для получения элементов из массива и для обмена значениями. Не нужно делать временные референсы – сэкономите время.
  • Не используйте деструктуризацию массива для нескольких возвращаемых значений, вместо этого используйте деструктуризацию объекта.

Классы и объекты

Text

Каждый объект в JavaScript имеет прототип, который является другим объектом. Все объекты в JavaScript наследуют методы и свойства от своего прототипа.

ES5

var Animal = (function () {
  function MyConstructor(name) {
    this.name = name;
  }
  MyConstructor.prototype.speak = function speak() {
    console.log(this.name + ' makes a noise.');
  };
  return MyConstructor;
})();

var animal = new Animal('animal');
animal.speak(); // animal makes a noise.

ES6

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

const animal = new Animal('animal');
animal.speak(); // animal makes a noise.

Классы и объекты

Text

Советы:

 

  • Всегда используйте синтаксис class и не изменяйте prototype напрямую. Код будет лаконичнее и его будет легче понять.
  • Избегайте создания пустого конструктора. У классов есть конструктор по умолчанию если не задать собственный.

 

О чём стоит помнить:

 

  • Объявления классов не поднимаются наверх (not hoisted). Сначала нужно объявить класс и только после этого использовать его, иначе будет ошибка ReferenceError.
  • Нет необходимости использовать ключевое слово function во время задания функций внутри определения класса.

Наследование

Text

ES5

var Lion = (function () {
  function MyConstructor(name){
    Animal.call(this, name);
  }

  // prototypal inheritance
  MyConstructor.prototype = Object.create(Animal.prototype);
  MyConstructor.prototype.constructor = Animal;

  MyConstructor.prototype.speak = function speak() {
    Animal.prototype.speak.call(this);
    console.log(this.name + ' roars ');
  };
  return MyConstructor;
})();

var lion = new Lion('Simba');
lion.speak(); // Simba makes a noise.
// Simba roars.

ES6

class Lion extends Animal {
  speak() {
    super.speak();
    console.log(this.name + ' roars ');
  }
}

const lion = new Lion('Simba');
lion.speak(); // Simba makes a noise.
// Simba roars.
  • напрямую вызываем конструкторAnimal с параметрами.
  • назначаем прототип Lion прототипом класса Animal.
  •  вызываем метод speak из родительского класса Animal.

промисы

Text

ES5

function printAfterTimeout(string, timeout, done){
  setTimeout(function(){
    done(string);
  }, timeout);
}

printAfterTimeout('Hello ', 1000, function(result){
  console.log(result);

  // nested callback
  printAfterTimeout(result + 'Reader', 1000, function(result){
    console.log(result);
  });
});

ES6

function printAfterTimeout(string, timeout){
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      resolve(string);
    }, timeout);
  });
}

printAfterTimeout('Hello ', 1000).then((result) => {
  console.log(result);
  return printAfterTimeout(result + 'Reader', 1000);

}).then((result) => {
  console.log(result);
});

Генераторы

Text

function *infiniteNumbers() {
    var n = 1;
    while (true) {
        yield n++;
    }
}

var numbers = infiniteNumbers(); // возвращает перебираемый объект

numbers.next(); // { value: 1, done: false }
numbers.next(); // { value: 2, done: false }
numbers.next(); // { value: 3, done: false }

Функции-генераторы представляют собой новую особенность ES6, которая позволяет функции создавать много значений в течение некоторого периода времени, возвращая объект (называемый генератором), который может быть итерирован для выброса значений из функции по одному за раз.

Тип данных Symbol

Text

Целью Symbol является создание уникального идентификатора, к которому нельзя получить доступ.

var sym = Symbol("опциональное описание");
console.log(typeof sym); // symbol
var o = {
    val: 10,
    [Symbol("случайный")]: "Я - символ",
};

console.log(Object.getOwnPropertyNames(o)); 
// val

 использовать new вместе с Symbol(…) нельзя.

 

Если Symbol используется как свойство/ключ объекта, он сохраняется таким специальным образом, что свойство не будет показано при нормальном перечислении свойств объекта.

Чтобы извлечь символьные свойства объекта, нужно использовать Object.getOwnPropertySymbols(o)

THANKS FOR YOUR ATTENTION

ES6

ES6

By ilyinalada

ES6

  • 266