FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
- 3. 3CONFIDENTIAL
1. npm install gulp && npm install gulp –g
2. npm install babel-core babel-preset-es2015 --save-dev
3. npm install gulp-babel –save-dev
4. create .babelrc: { “presets”: [“es2015”] }
5. rename “gulpfile.js” to “gulpfile.babel.js”
КАК НАЧАТЬ ПИСАТЬ НА ES6?
- 4. 4CONFIDENTIAL
'use strict';
import gulp from 'gulp';
const dirs = {
src: 'src',
dest: 'build'
};
gulp.task('default', () => {
return gulp.src(`${dirs.src}/app.js`)
//some actions
.pipe(gulp.dest(`${dirs.dest}`));
});
GULPFILE.BABEL.JS
- 6. 6CONFIDENTIAL
SCOPING. BLOCK-SCOPED VARIABLES
Ecmascript6
Ecmascript5
let callbacks = [];
for(let i = 0; i <= 2; i++){
callbacks[i] = function(){
return i * 2;
}
}
var i, callbacks = [];
for(i = 0; i <= 2; i++){
callbacks[i] = function(){
return i * 2;
};
}
var i, callbacks = [];
for(i = 0; i <= 2; i++){
(function(i){
callbacks[i] = function(){
return i * 2;
};
})(i);
}
callbacks[0]() === 0; //true
callbacks[1]() === 2; //true
callbacks[2]() === 4; //true
- 7. 7CONFIDENTIAL
ARROW FUNCTION. EXPRESSION BODIES
Ecmascript6Ecmascript5
odds = evens.map(v => v + 1);
pairs = evens.map(v => ({even: v, odd: v + 1 }));
nums = evens.map((v, i) => v + i);
odds = evens.map(function(v){
return v + 1;
});
pairs = evens.map(function(v){
return { even: v, odd: v + 1 };
});
nums = evens.map(function(v, i){
return v + i;
});
- 9. 9CONFIDENTIAL
ARROW FUNCTION. LEXICAL THIS
Ecmascript5 Ecmascript6
var self = this;
this.nums.forEach(function(v){
if(v % 5 === 0)
self.fives.push(v);
});
this.nums.forEach(v => {
if(v % 5 === 0)
this.fives.push(v);
});
- 10. 10CONFIDENTIAL
EXTENDED PARAMETER HANDLING. DEFAULT PARAMETER
VALUES
Ecmascript5 Ecmascript6
function f(x, y, z){
if (y === undefined)
y = 7;
if (z === undefined)
z = 42;
return x + y + z;
};
f(1) === 50;//true
function f(x, y = 7, z = 42){
return x + y + z;
};
f(1) === 50;//true
- 11. 11CONFIDENTIAL
EXTENDED PARAMETER HANDLING. REST PARAMETER
Ecmascript6
function f(x, y){
var a = Array.prototype.slice.call(arguments, 2);
return (x + y) * a.length;
};
f(1, 2, 'hello', true, 7) === 9;//true
function f(x, y, ...a){
return (x + y) * a.length;
};
f(1, 2, 'hello', true, 7) === 9;//true
Ecmascript5
- 12. 12CONFIDENTIAL
EXTENDED PARAMETER HANDLING. SPREAD OPERATOR
Ecmascript6
var params = ['hello', true, 7];
var other = [1, 2].concat(params);
f.apply(undefined, [1, 2].concat(params)) === 9;//true
var str = 'foo';
var chars = str.split(''); //['f','o','o']
var params = ['hello', true, 7];
var other = [1, 2, ...params]; //[1, 2, 'hello', true,
7]
f(1,2, ...params) === 9;
var str = 'foo';
var charts = [ ...str]; //['f','o','o']
Ecmascript5
- 13. 13CONFIDENTIAL
TEMPLATE LITERALS. STRING INTERPOLATION
Ecmascript6
message = 'Hello ' + customer.name + '.n' +
'want to by ' + card.amout + ' ' + card.product + ' for.n' +
'a total of ' + (card.amount + card.unitprice) + ' bucks?';
message = `Hello ${customer.name}. want to buy
${card.amount} $(card.product} for a total of
${(card.amount * card.unitprice)} bucks?`;
Ecmascript5
var customer = { name: 'Foo'};
var card = { amount: 7, product: 'Bar', unitprice: 42};
- 14. 14CONFIDENTIAL
EXTENDED LITERALS. BINARY & OCTAL LITERAL
Ecmascript6
parseInt('111110111', 2) === 503;//true
parseInt('767', 8) === 503; //true
0b111110111 === 503;//true
0o767 === 503;//true
Ecmascript5
- 15. 15CONFIDENTIAL
ENHANCED OBJECT PROPERTIES. PROPERTY SHORTHAND
COMPUTED PROPERTY NAMES
Ecmascript6
var obj = { x: x, y: y };
var obj = {
foo: "bar”
};
obj["baz" + quux()] = 42;
let obj = { x, y };
let obj = {
foo: "bar",
[ "baz" + quux() ]: 42
};
Ecmascript5
- 16. 16CONFIDENTIAL
ENHANCED OBJECT PROPERTIES. METHOD PROPERTIES
Ecmascript6
var obj = {
foo: function(a, b){
//...
},
boo: function(a, b){
//...
}
};
var obj = {
foo(a, b){
//...
},
boo(a, b){
//...
},
};
Ecmascript5
- 17. 17CONFIDENTIAL
DESTRUCTURING ASSIGNMENT. ARRAY MATCHING
Ecmascript6
var list = [1, 2, 3];
var a = list[0], b = list[2];
var tmp = a; a = b; b = tmp;
var list = [1, 2, 3];
var [ a, , b ] = list;
[ b, a ] = [ a, b ];
Ecmascript5
- 19. 19CONFIDENTIAL
DESTRUCTURING ASSIGNMENT. FAIL-SOFT DESTRUCTURING
Ecmascript6
var list = [ 7 ];
var a = typeof list[0] !== 'undefined' ? list[0] : 1;
var b = typeof list[1] !== 'undefined' ? list[1] : 2;
var d = typeof list[2] !== 'undefined' ? list[2] :
undefined;
a === 7;//true
b === 42;//true
d === undefined;//true
var list = [ 7 ];
var [ a = 1, b = 42, d ] = list;
a === 7;//true
b === 42;//true
d === undefined;//true
Ecmascript5
- 20. 20CONFIDENTIAL
MODULES. VALUE EXPORT/IMPORT
Ecmascript6
//math.js
var LibMath = {};
LibMath.sum = function(x, y){
//..
};
LibMath.pi = 3.14159;
//someApp.js
var math = LibMath;
var a = math.sum(math.pi,math.pi);
export * from 'lib/math';
export var e = 2.7182818286;
export default (x) => Math.exp(x);
import exp, {pi, e} from 'lib/mathplusplus';
var a = exp(pi);
Ecmascript5
- 21. 21CONFIDENTIAL
CLASSES. CLASS DEFINITION
Ecmascript6
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;
}
};
Ecmascript5
- 22. 22CONFIDENTIAL
CLASSES. CLASS INHERITANCE
var Shape = function(id, x, y){ //… };
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;
Ecmascript5
- 23. 23CONFIDENTIAL
class Shape { //… };
class Rectangle extends Shape {
constructor(id, x, y, width, height){
super(id, x, y);
this.width = width;
this.height = height;
}
};
Ecmascript6
- 24. 24CONFIDENTIAL
SYMBOL TYPE
Symbol('foo') !== Symbol('foo');//true
const foo = Sybmol(‘foo’);
const boo = Symbol();
typeof foo === 'symbol'; //true
typeof boo === 'symbol'; //true
let obj = {};
obj[foo] = 'foo';
obj[boo] = 'boo';
JSON.stringify(obj); //{}
Object.keys(obj);//[]
Object.getOwnPropertyNames(obj);//[]
Object.getOwnPropertySymbols(obj);//[foo, bar]
- 26. 26CONFIDENTIAL
ITERATORS. ITERATOR & FOR-OF OPERATOR
let fibonacci = {
[Symbol.iterator](){
let pre = 0, cur = 1;
return {
next(){
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur };
}
}
}
};
for(let n of fibonacci){
if(n > 1000)
break;
console.log(n);
}
- 29. 29CONFIDENTIAL
GENERATORS. SIMPLEST ASYNC
function request(url){
makeAjaxCall(url, function(response){
it.next(response);
});
};
function *main(){
var result1 = yield request('http://some.url.1');
var data = JSON.parse(result1);
var result2 = yield request('http://some.url.2?id=' + data.id);
var data = JSON.parse(result2);
};
var it = main();
it.next();
- 30. 30CONFIDENTIAL
MAP/SET & WEAKMAP/WEAKSET. MAP DATA-STRUCTURE
Ecmascript6
var m = {};
m['hello'] = 42;
Object.keys(m).length;//1
for(key in m){
if(m.hasOwnProperty(key)){
console.log(key + ' = ' + m[key]);
}
}
//hello = 42
let m = new Map();
m.set('hello', 42);
m.set('s', 34);
m.get('s');//34
for(let [key, val] of m.entities())
console.log(key + ' = ' + val);
//hello = 42
//s = 34
Ecmascript5
- 31. 31CONFIDENTIAL
MAP/SET & WEAKMAP/WEAKSET. WEAK-LINK DATA-
STRUCTURES
var ws = new WeakSet();
var obj = {};
var foo = {};
ws.add(window);
ws.add(obj);
ws.has(window);//true
ws.has(obj);//true
ws.has(foo);//false
- 34. 34CONFIDENTIAL
NEW BUILT-IN METHODS. STRING REPEATING AND
SEARCHING
Ecmascript6
Array(4 + 1).join(' ');
'hello'.indexOf('ello') === 1;//true;
' '.repeat(4);
'hello'.startWith('ello',1);
'hello'.includes('ell');
'hello'.includes('ell', 1);
Ecmascript5
- 36. 36CONFIDENTIAL
PROMISES. PROMISE USAGE
function msgAfterTimeout(msg, who, timeout, onDone){
setTimeout(function(){
onDone(msg + 'Hello' + who + '!');
},timeout);
};
msgAfterTimeout(' ', 'Foo',100, function(msg){
msgAfterTimeout(' ', 'Foo', 200, function(msg){
console.log('done after 300ms' + msg);
});
});
Ecmascript5
- 37. 37CONFIDENTIAL
PROMISES. PROMISE USAGE
Ecmascript6 function msgAfterTimeout(msg,who,timeout){
return new Promise((resolve, reject) => {
setTimeout(() => resolve(`${msg} Hello ${who}`), timeout);
});
};
msgAfterTimeout(’ ’, 'Foo', 100).then((msg) =>
msgAfterTimeout(’ ', 'Foo', 200).then((msg) =>{
console.log('done after 300ms' + msg);
});
- 38. 38CONFIDENTIAL
META-PROGRAMMING. 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'
- 39. 39CONFIDENTIAL
META-PROGRAMMING. REFLECTION
Ecmascript6
var obj = { a: 1 };
Object.defineProperty(obj, 'b', { value: 2 });
Object.getOwnPropertyNames(obj); //['a','b'];
let obj = { a: 1 };
Object.defineProperty(obj, 'b', { value: 2 });
obj[Symbol('c')] = 3;
Reflect.ownKeys(obj); // ['a', 'b', Symbol(c) ];
Ecmascript5