ES6
Какие новинки появились в ES6? Что такое ES-2015? В чем отличия ES6 и ES-2015? Стоит ли писать на ES6? Все браузеры поддерживают ES6? Что делать если браузер не поддерживает ES6?
ES-6 и ES-2015 это одно и тоже. Большиство браузеров до сих пор не поддерживает ES6, но писать код все равно стоит по новому - а для работы в браузерах нужно использовать транспайлер (Babel) - который преобразует ES6 в ES5(или ES3). Список новинок ниже:
use strick
let & const
Это новые виды переменных добавленные в ES6.
Переменная let имеет 4 основных отличия от var:
- Область видимости - блочная (у var область видимости ограничена function)
- Переменная let видна только после объявления. Для примера возьмем код:
function test(){
console.log(a); //(1)
var a = 5;
console.log(a);//(2)
};
test();
в строке (1) мы получим undifined, а в (2) мы получим 5. Так происходит потому что на самом деле интерпретатор преобразует код:
function test(){
var a;
console.log(a);
a = 5;
console.log(a);
};
test();
если в предыдущих примерах var заменить на let, то мы получим ошибку ReferenceError в строке (1), т.к. let (и const) не поддерживают "всплытие".
- При использовании в цикле - каждый раз создается новая независимая переменная (при использовании var - эта переменная одна на каждую итерацию -> как результат типичная ошибка замыкания и цикла).
- нельзя пере объявлять в одном блоке:
let a = 5; let a = 2; //ReferenceError
Переменная const аналогична let, за одним маленьким исключением при ее объявлении необходимо переменную сразу же инициализировать значением и в последствии эту переменную уже нельзя изменить.
const a; //ReferenceError
const a = 5;
a = 6; // TypeError;
Деструктуризация
Диструктуризация - это синтаксическое присвоение, с помощью которого можно присвоить массив или объект сразу нескольким переменным, разбив его на части.
var user = {
name: 'Tom',
age: 28
};
let {name, age} = user;
В результате мы получим две переменные name
и age
. Заметьте что имена переменных в примере совпадают со свойствами в объекте (иначе присвоение не удалось). Но можно задать свои имя:
let {name: firstName, age} = user;
Также есть возможность задать значение по умолчанию:
let {name: firstName = 'Джейн До', age = 0} = user;
еще мы можем:
var user1 = {
name: 'Tom',
age: 28
};
var user2 = {
name: 'Jerry',
age: 20
};
let{name, age} = {user1, user2};
В этом случае переменная name = 'Tom'
, а переменная age = 20
.
Если объект у нас сложной структуры (в сложеными свойствами) - нам нужно просто сохранить эту структуру в деструктуризации.
Можем применить спред-оператор:
let {var1, var2, ...rest} = 'Hello world! I'm Tom'.split(' ');
var1; //Hello
var2; //world!
rest; //['I'm', 'Tom']
При работе с массивами мы не можем менять имена переменных, но мы можем задавать значение по умолчанию:
let [var1, var2 = 0, ...rest] = array;
Также появилась декстуризация параметров:
var user = {name: 'Tom', age: 27};
function test({name, age}){
...
};
test(user);
Спред оператор
Спред оператор (spread) - это оператор расширения, позволяет расширять выражение в тех местах, где предусмотрено использование нескольких аргументов.
Стрелочная функция =>
Стрелочная функция - это более простой и компактный способ записи ананимной функции.
let func = (args) = > { ... to do something with args };
Помимо компактности, она имеет еще одно замечательное свойство - сохраняет контекст в рамках которого была вызвана. По сути () =>
это тоже самое что и .bind(this)
.
Но есть и ограничения - такую функцию нельзя использовать в качестве конструктора.
Также у стрелочной функции нет своиего arguments
- она получает его из окружающего контекста.
Строчные шаблоны
Появился новый вид ковычек "обратные ковычки", с их помощью мы можем не использовать символ перевода строки \n
:
console.log(`Hello
world!`);
//в результате получим
//Hello
//world!
также можем использовать js код внутри строки
var name = 'Tom';
console.log(`Hello! I'm ${name}`);
//Hello! I'm Tom
Class
Появилась новая конструкция class
- это синтаксический сахар.
class User extends Parent{ //организация наследования, тоже самое что и User.prototype = Object.create(Parent.prototype)
constructor(name){
super(name); //super - должен быть обязательно до обращения до this, т.к. до super - this не существует
this.name = name;
}
get name(){
return this.name;
}
set name(newName){
this.name = newName;
}
sayHi(){ //методы записываются в прототип User.prototype.sayHi
cosnole.log(`Hi! My name ${this.name}`);
}
static test(){ //статический метод, можно обращаться User.test()
...
}
}
var user = new User('Tom'); //создание класса только с кл.словом new
user.name; // будет использоваться геттер
user.name = 'Jerry'; // будет использоваться сеттер
Еще одна особености конструкции class
- это отсутствие hoisting и блочная область видимости (как у переменных let
и const
)
Также все методы класса не перечисляемые.