ECMAScript 6
under the microscope
Andrei Pfeiffer
@pfeiffer_andrei


/andreipfeiffer

// code designer

// co-organizer & speaker
// dev author

5620 LOC
// Client: 1500 src + 1350 tests
// Server: 2200 src + 570 tests
/* - arrow functions - modules - object enhanced literals - built-in extensions - SystemJS - Karma tests + coverage - build system + workflow setup */
5 days
build-in extensions
// new methods on existing prototypes
String.startsWith()
var str = "es6 features"; str.startsWith("es6"); // true
// instead of ES5 ( str.indexOf("es6") === 0 );
String.endsWith()
var str = "es6 features"; str.endsWith("features"); // true
// instead of ES5 var str = "es6 features", s = "features"; ( str.indexOf(s, str.length - s.length) > -1 );
String.includes()
var str = "es6 features"; str.includes("es6"); // true str.includes("es6", 1); // false
// instead of ES5 (str.indexOf("es6") > -1);
Array.find()
var arr = [
{ a: 1, b: 10 },
{ a: 2, b: 20 }
];
arr.find(item => item.a > 0);
// { a: 1, b: 10 }
// instead of ES5 arr.filter(function(item) { return item.a > 0; })[0];
Array.findIndex()
var arr = [
{ a: 1, b: 10 },
{ a: 2, b: 20 }
];
arr.findIndex(item => item.a > 0);
// 0
// instead of ES5 var index; arr.some(function(item, i) { if ( item.a > 1 ) { index = i; return true; } });
Array.includes()
var arr = [1, 2, 3]; arr.includes(2); // true arr.includes(2, 2); // false
var arr = [{}];
arr.includes({});
// false
var obj = {},
arr = [obj];
arr.includes(obj);
// true
Array.fill()
var arr = [1, 2, 3]; arr.fill( null ); // [null, null, null]
// instead of ES5 arr.forEach((item, index) => { arr[index] = null; });
// array with fixed number // of repeating elements var arr = Array(3).fill( null ); // [null, null, null];
Object.assign()
var o1 = { a: 1 },
o2 = { a: 2, b: 2 };
var o3 = Object.assign({}, o1, o2);
// {a: 2, b: 2}
// no more $.extend(); // jQuery angular.extend(); // AngularJS _.extend // underscore require(util)._extend; // Node.js
Node.js
4.x
4.x
flag
Babel
5.x
plugin
plugin
support
* Object.assign() Array.includes()
object enhanced literals
// easier object definition
shorthand
methods & properties
var name = "Andrei Pfeiffer";
var obj = {
name,
getName() {
return this.name;
}
};
// instead of ES5 var obj = { name: name, getName: function() { return this.name; } };
computed
methods & properties
var name = "Name";
var obj = {
["last" + name]: "Pfeiffer",
["get" + name]() { /*...*/ }
};
obj.firstName;
obj.getName();
// instead of ES5 var obj = {}; obj["last" + name] = "Pfeiffer"; obj["get" + name] = function() { /*...*/ };
modules
// code isolation
// module pattern var myModule = (function() { "use strict"; var secret = 'secret'; return { getSecret: function() { return secret; } }; })();
no more IIFE
// no global scope pollution
var myModule = (function() {"use strict"; var secret = 'secret'; return { getSecret: function() { return secret; } };})();
no more "use strict"
// implicit Strict Mode
var myModule = (function() {"use strict";var secret = 'secret'; return { getSecret: function() { return secret; } };})();
var secret = 'secret';
export function getSecret() {
return secret;
};
secure APIs
// exports are immutable
// secret.js var secret = 'secret'; export function getSecret() { return secret; };
// secret.js export const secret = 'secret';
// app.js import {secret} from "./secret"; console.log( secret ); // "secret" secret = "no secret"; // TypeError
zero globals
long import lists
// userController.js import config from './config'; import filters from './filters'; import { search } from './utils'; import UserService from './services/user'; /* ... */
arrow functions
// anonymous function expressions
// replace "function" with "=>" // and move it after params var foo =function(id) => { return request.get(id); };
inline simple functions
// 2 LOC less
// single statement functions var foo = id => request.get(id);
// instead of ES5 var foo = function(id) { return request.get(id); };
// no inline for 2 statements var foo = (id) => { validate(id); return request.get(id); };
// or for long single statements var foo = (id) => { validate(id) .then( request.get(id) ) .then( (data) => render(data) ); };
implicit this
// auto-bound to object
// this references outer context (: yey var obj = { name: '', init() { $.get().then(x => { this.name = x; }); } };
// instead of ES5 var obj = { name: '', init: function() { var self = this; $.get().then(function(x) { self.name = x; }); } };
// caution with jQuery events $('a').click(function() { $(this).toggleClass('active'); }); // this = DOM element
// this references outer context ): shit $('a').click(() => { $(this).toggleClass('active'); }); // this = undefined
// caution with Angular repeaters <div ng-repeat="items"> <button ng-click="do()"></button> </div>
// this references iterated item $scope.do = function() { console.log(this); }; // [Object]
// this references outer scope $scope.do = () => { console.log(this); }; // undefined
// solution: pass data explicitly <div ng-repeat="items"> <button ng-click="do($data)"></button> </div>
// don't rely on context $scope.do = (data) => { console.log(data); }; // [Object]
implicit return
// aka "expression closure"
// without braces, implicit return var foo = () => 1; foo(); // 1
// with braces, no implicit return var foo = () => { 1 }; foo(); // undefined
// requires explicit return var foo = () => { return 1; }; foo(); // 1
// we can implicitly return arrays var foo = () => [1, 2]; foo(); // [1, 2]
// but not objects var foo = () => {a: 1}; foo(); // undefined
// objects need to be wrapped var foo = () => ({a: 1}); foo(); // {a: 1}
conclusions
built-in extensions
// nice to have
// write less, do more
enhanced object literals
// probably best addition
modules
// non-trivial to setup
// great for FP, composition
arrow functions
// great for callbacks (!!! this)
// declarations are still valid
..?
thank you
JavaScript Vanilla #5 - ES6 under the microscope
By Andrei Pfeiffer
JavaScript Vanilla #5 - ES6 under the microscope
In this presentation I will talk about some of the features introduced in ES6, namely: useful new methods on existing prototypes, object enhanced literals, the benefits of modules & the pros & gotchas of arrow functions.
- 1,133