ES2015
2015
История
-
ES5 вышел в 2009
-
В том же году запустили проект "Harmony"
-
ES6 был принят в июне 2015 спустя 6 лет
Зачем?
Новые фичи
Блочная область видимости
let
var data = [1,2,3];
for (let i = 0; i < data.length; i++) {
console.log(data[i]);
}
console.log(i); // > i is not defined
var data = [1,2,3];
(function(){
for (var i = 0; i < data.length; i++) {
console.log(data[i]);
}
})();
console.log(i); // > i is not defined
const
Object.defineProperty(
window,
"PI",
{
value: 3.141593,
enumerable: true,
writable: false,
configurable: false
})
PI > 3.0;
const PI = 3.141593;
PI = 10;
// > Uncaught TypeError:
Assignment to constant variable.
Функции
Параметры по умолчанию
function sum(x,y) {
x = x || 1;
y = y || 2;
return x + y;
}
function sum(x = 1, y = 2) {
return x + y;
}
sum(); // > 3
sum(1,2); // > 3
sum(4); // > 6
Стрелочные функции
let data = [0,1,2,3,4];
data.map(function(i) { return i*2});
// > [0,2,4,6,8]
data.map(i => i*2);
// > [0,2,4,6,8]
Сохранение контекста
setTimeout(function(){
console.log(this.name);
}, 100);
setTimeout(() => {
console.log(this.name);
}, 100);
destructuring
Деструктивное присвоение
var a, b;
[a, b] = [1, 2];
// Зачение по умолчанию )
var [a = 1] = [];
a === 1;
Свитчь переменных :)
var a = 1;
var b = 3;
[a, b] = [b, a];
Пропуск переменных
var a,b;
[a, ,b] = [1,2,3];
Деструкция объектов
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
// Можно задать новые имена переменным
var {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
Деструкция параметров функции
function log({message = '', type = 'error'})
{
console.log(type, message);
}
log({
type: 'warn',
message: 'hello'
})
Object Literals
Object
var obj = {
// __proto__ - легально
__proto__: theProtoObj,
// Сокращение для ‘handler: handler’
handler,
// Краткая запись методов
toString() {
// вызов метода прототипа
return "d " + super.toString();
},
// вычесление параметра
[ 'prop_' + (() => 42)() ]: 42
};
Шаблоные строки
Многострчоные строки
'Я однострочная строка в js ((';
[
'Текст',
'Текст',
].join('');
'Текст' +
'Текст';
`А теперь можно
так.`
`А теперь можно
так.`
Шаблонизация из коробки
var user = "Павел";
var post = "Директор";
var count = 4;
var msg = `
Пользователь: ${user}.
Должность: ${post}
Количесво: ${count}
`;
Тэгирование строк
var a = 5;
var b = 10;
function tag(strings, ...values) {
console.log(strings[0]); // "Hello "
console.log(strings[1]); // " world"
console.log(values[0]); // 15
console.log(values[1]); // 50
return "Строка";
}
tag`Hello ${ a + b } world ${ a * b}`;
// > "Строка"
Новые методы
Объединение объектов
var dst = { quux: 0 };
var src1 = { foo: 1, bar: 2 };
var src2 = { foo: 3, baz: 4 };
Object.assign(dst, src1, src2);
dst.quux === 0;
dst.foo === 3;
dst.bar === 2;
dst.baz === 4;
Объединение объектов ES5
var dst = { quux: 0 };
var src1 = { foo: 1, bar: 2 };
var src2 = { foo: 3, baz: 4 };
Object.keys(src1).forEach(function(k) {
dst[k] = src1[k];
});
Object.keys(src2).forEach(function(e) {
dst[k] = src2[k];
});
dst.quux === 0;
dst.foo === 3;
dst.bar === 2;
dst.baz === 4;
array find
[ 1, 3, 4, 2 ].find(x => x > 3); // 4
[ 1, 3, 4, 2 ].filter(function (x) { return x > 3; })[0]; // 4
String
"foo".repeat(3);
"hello".startsWith("ello", 1); // true
"hello".endsWith("hell", 4); // true
"hello".includes("ell"); // true
"hello".includes("ell", 2); // false
Number
Number.isNaN(42) === false;
Number.isNaN(NaN) === true;
Number.isFinite(Infinity) === false;
Number.isFinite(-Infinity) === false;
Number.isFinite(NaN) === false;
Number.isFinite(123) === true;
Number
Number.isSafeInteger(42) === true;
Number.isSafeInteger(9007199254740992) === false;
console.log(0.1 + 0.2 === 0.3); // false
console.log(Math.abs((0.1 + 0.2) - 0.3) < Number.EPSILON); // true
console.log(Math.trunc(42.7)) // 42
console.log(Math.trunc( 0.1)) // 0
console.log(Math.trunc(-0.1)) // -0
set
set
let s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
for (let key of s.values())
console.log(key);
set ES5
var s = {};
s["hello"] = true; s["goodbye"] = true; s["hello"] = true;
Object.keys(s).length === 2;
s["hello"] === true;
for (var key in s)
if (s.hasOwnProperty(key))
console.log(s[key]);
set
let mySet = new Set();
var o = {a: 1, b: 2};
mySet.add(o);
mySet.has(o); // true
mySet.add(document.body);
mySet.has(document.querySelector("body")); // true
mySet[0]// не работает
set
var mySet = new Set([1,2,3,4]);
[v for (v of mySet)]; // [1,2,3,4]
Array.from(mySet); // [1,2,3,4]
[...mySet2]; // [1,2,3,4]
for (let item of mySet) console.log(item);
mySet.forEach((value) => console.log(value));
map
map
let m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) === 34;
m.size === 2;
for (let [ key, val ] of m.entries())
console.log(key + " = " + val);
map ES5
var m = {};
m["hello"] = 42;
// нету в ES5
// нету в ES5
Object.keys(m).length === 2;
for (key in m) {
if (m.hasOwnProperty(key)) {
var val = m[key];
console.log(key + " = " + val);
}
}
rest и spread
...
Развертка
function f(x, y, z) { }
var args = [0, 1, 2];
f(...args);
Мерж масивов
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
Свертка
function test(a,b ...data) {
console.log(a,b,data);
}
test(1,2,3,4,5);
// > 1,2,[3,4,5]
Классы
Классы в ES5
var Shape = function (id, x, y) {
this.id = id;
this.move(x, y);
};
Shape.prototype.move = function (x, y) {
this.x = x;
this.y = y;
};
Конструктор
class Shape {
constructor (id, x, y) {
this.id = id;
this.move(x, y);
}
move (x, y) {
this.x = x;
this.y = y;
}
}
Наследование
class Rectangle extends Shape {
constructor (id, x, y, width, height) {
super(id, x, y);
this.width = width;
this.height = height;
}
}
class Circle extends Shape {
constructor (id, x, y, radius) {
super(id, x, y);
this.radius = radius;
}
}
Наследование ES5
var Rectangle = function (id, x, y, width, height) {
Shape.call(this, id, x, y);
this.width = width;
this.height = height;
};
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var Circle = function (id, x, y, radius) {
Shape.call(this, id, x, y);
this.radius = radius;
};
Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;
Статические методы
class gameObject {
move(x,y) {
...
},
static getWorld() {
return 'world';
}
};
gameObject.getWorld();
// > 'world';
Символы
Symbol
Symbol("foo") !== Symbol("foo");
const foo = Symbol();
const bar = Symbol();
typeof foo === "symbol";
typeof bar === "symbol";
let obj = {};
obj[foo] = "foo";
obj[bar] = "bar";
JSON.stringify(obj); // {}
Object.keys(obj); // []
Object.getOwnPropertyNames(obj); // []
Object.getOwnPropertySymbols(obj); // [ foo, bar ]
Symbol
var role = Symbol();
var user = {
id: 1001,
name: 'Administrator',
[role]: 'admin'
};
var firstScore = Symbol('score');
var secondScore = Symbol('score');
firstScore === secondScore; // false
Интераторы
и
for of
Интератор
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next () {
[ pre, cur ] = [ cur, pre + cur ];
return { done: false, value: cur };
}
};
}
}
for of
for (let n of fibonacci) {
if (n > 1000)
break;
console.log(n);
}
Генераторы
генератор
let fibonacci = function* (numbers) {
let pre = 0, cur = 1;
while (numbers-- > 0) {
[ pre, cur ] = [ cur, pre + cur ];
yield cur;
}
};
использование
for (let n of fibonacci(1000))
console.log(n);
let numbers = [ ...fibonacci(1000) ];
let [ n1, n2, n3, ...others ] = fibonacci(1000);
Promises
Promises
function msgAfterTimeout (msg, who, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(`${msg} Hello ${who}!`), timeout);
});
}
msgAfterTimeout("", "Foo", 100).then((msg) =>
msgAfterTimeout(msg, "Bar", 200);
).then((msg) => {
console.log(`done after 300ms:${msg}`);
});
Promises
Promise.all([
fetchPromised("http://backend/foo.txt", 500),
fetchPromised("http://backend/bar.txt", 500),
fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
let [ foo, bar, baz ] = data;
console.log(`success: foo=${foo} bar=${bar} baz=${baz}`);
}, (err) => {
console.log(`error: ${err}`);
});
Proxying
Proxying
let target = {
foo: "Welcome, foo"
};
let proxy = new Proxy(target, {
get (receiver, name) {
return name in receiver ? receiver[name] : `Hello, ${name}`;
}
});
proxy.foo === "Welcome, foo";
proxy.world === "Hello, world";
Модули
export
export myFunction;
export const foo = Math.sqrt(2);
export default myFunctionOrClass;
export
export var x = 42;
export function foo() {};
export default 42;
export default function foo() {};
export { encrypt };
export { decrypt as dec };
export { encrypt as en } from 'crypto';
export * from 'crypto';
import
import 'jquery';
import $ from 'jquery';
import { $ } from 'jquery';
import { $ as jQuery } from 'jquery';
import * as crypto from 'crypto';
транспайлер – переписывающий код на ES-2015
ES2015
Всем спасибо!
Андреев Сергей
US
Ведущий front-end разработчи
ES2015
By Sergey Andreev
ES2015
- 1,343