Last active
August 29, 2015 14:27
-
-
Save pyadav/1378d3414eaf244c3566 to your computer and use it in GitHub Desktop.
Ecmascript features list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ES2015 (a.k.a. ES6) | |
- Lots of new language features | |
- Classes | |
- Arrow Functions | |
- Destructuring | |
- Let + Const | |
- Iterators | |
- Generators | |
- Modules | |
- Unicode support | |
- Much more! | |
- "Doesn't look like JavaScript" | |
Babel | |
- The one library you'll need to develop modern JavaScript™ | |
- Has the best support for next generation JavaScript | |
- Most importantly, it's very easy to use | |
- Server side executable via babel-node | |
- Client side transformations | |
- Shared runtime | |
- Shared configuration via .babelrc | |
- Source map support | |
- JSX Support & Optimizations | |
- Plugins | |
Modules | |
import React from "react"; | |
// var React = require("react"); | |
import {serverPort} from "./appConfig"; | |
// var serverPort = require("./appConfig").serverPort; | |
export default {}; | |
// module.exports = {}; | |
export default class {}; | |
export default class extends React.Component {}; | |
export default new class {}; | |
Classes | |
class BaseAction { | |
dispatch() { | |
// do stuff | |
} | |
} | |
class SomeAction extends BaseAction { | |
constructor() { | |
super(); | |
this.dispatch(); | |
} | |
} | |
Generators | |
- "Generators are functions which can be exited | |
and later re-entered. Their context | |
(variable bindings) will be saved across | |
re-entrances." | |
~ MDN | |
- A way to control flow of a function. | |
Pause, resume, return, and throw. | |
- Can aide in the use of async operations | |
without resorting to callbacks | |
- async/await | |
- Iterators | |
- for ... of | |
- https://github.com/getify/You-Dont-Know-JS/blob/master/async%20&%20performance/ch4.md | |
io.js | |
- "Bringing ES6 to the Node Community!" | |
- Natively runs ES2015 code without any additional flags | |
- (With limited support. See above compatibility table) | |
- Can natively run Koa.js generators and promises | |
- Node 0.12 can run generators and promises natively too | |
- Requires the --harmony flag | |
React | |
- Describe your HTML in JavaScript | |
- React will figure out what to render from that | |
- Can render your HTML to a Static Markup | |
- React.renderToStaticMarkup(<Component />); | |
- We're able to use React Components as server side | |
templates | |
- Reuse developer skillsets on server and client | |
WebPack | |
- Transform and inline modules into static assets | |
- JavaScript | |
- CSS | |
- Images | |
- Define the transformations on modules using loaders | |
- babel-loader | |
- jsx-loader | |
- less-loader | |
- Can optimize for number of web requests, | |
payload size, etc. | |
- Define code split points and WebPack will form | |
async loaded chunks depending on your | |
optimization strategy | |
- Hot Module Reloading | |
- Will replace your module inline | |
- No page refresh | |
- Extensible via Plugins | |
Developing with WebPack | |
- Depending on your WebPack configuration, you likely | |
have a hash of each chunk included in the filename | |
- Something like main.09234919823fe8ac.js | |
- Good for long term caching purposes | |
- On a module change, WebPack will recompile the | |
chunks which will then have a different hash and | |
therefore a different filename | |
- This new filename needs to be communicated to our | |
React templates in order to serve the appropriate asset | |
- How could we accomplish this? | |
Flux | |
- Unidirectional data flow pattern | |
- Actions -> Dispatcher -> Stores -> Components -> Actions | |
- My talk at FITC Spotlight: Front-End | |
on different Front-End Paradigms | |
https://www.youtube.com/watch?v=mdHErrj2iV0 | |
- Maybe we can use Flux to update our WebPack | |
entrypoint URL? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// One liner | |
var nums = evens.map((v, i) => v + i); | |
// Longer | |
nums.forEach(v => { | |
if (v % 5 === 0) | |
fives.push(v); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Set up our async runners... | |
let doSomething = () => { | |
return new Promise((resolve,reject) => { | |
console.log('I like this...') | |
setTimeout(() => resolve('hi'), 1000); | |
}); | |
}, | |
appendSomething = (result1) => { | |
return new Promise((resolve,reject) => { | |
console.log('well maybe..') | |
setTimeout(() => resolve(result1 + ' hey there'), 1000); | |
}); | |
} | |
// Plain promises... | |
doSomething() | |
.then(appendSomething) | |
.then((result) => { | |
console.log(result); | |
}); | |
// ES7 | |
async () => { | |
let result = await doSomething(), | |
result2 = await appendSomething(result); | |
console.log(result2) | |
}(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ES7 | |
``` | |
async function f() { | |
await ... | |
} | |
``` | |
ES6 | |
``` | |
const f = async(function* () { | |
yield ... | |
}); | |
``` | |
*/ | |
function async(f) { | |
return function () { | |
let generator = f.apply(this, arguments); | |
return new Promise((resolve, reject) => { | |
let onValue = generator.next.bind(generator); | |
let onError = generator.throw.bind(generator); | |
(function step(callback) { | |
let next; | |
try { | |
next = callback(); | |
} catch (err) { | |
return reject(err); | |
} | |
if (next.done) resolve(next.value); | |
else if (next.value && next.value.then) Promise.resolve(next.value) | |
.then((value) => step(() => onValue(value)), (err) => step(() => onError(err))); | |
else step(() => onValue(value)); | |
}(onValue)); | |
}); | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class name { | |
constructor(name){ | |
this.name = name; | |
this.test = "test"; | |
} | |
render(){ | |
console.log(this.name); | |
} | |
} | |
//var tete = new name('arnaud'); | |
//tete.render(); // return arnaud | |
class pseudo extends name{ | |
constructor(name){ | |
super(name); | |
this._pseudo = 'le nul'; | |
} | |
get pseudo(){ // return pseudo | |
return this._pseudo; | |
} | |
set pseudo(val){ // Set the new value to pseudo | |
this._pseudo = val; | |
} | |
surname(){ | |
//console.log(this); // return titi {name: "arnaud", test: "test", _pseudo: "le meilleur"} | |
console.log(this.name + ' ' + this.pseudo); | |
} | |
} | |
var tutu = new pseudo("arnaud"); | |
tutu.surname(); // return "arnaud le nul" | |
tutu.pseudo = "le meilleur"; | |
tutu.surname(); // return "arnaud le meilleur" | |
//Tested here : http://bit.ly/1LlRNy0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// list matching | |
var [a, , b] = [1,2,3]; | |
// object matching shorthand | |
var {op, lhs, rhs} = getASTNode() | |
// Splat | |
function f(x, ...y) { | |
// y is an Array | |
return x * y.length; | |
} | |
f(3, "hello", true) == 6 | |
// Spread | |
function f(x, y, z) { | |
return x + y + z; | |
} | |
// Pass each elem of array as argument | |
f(...[1,2,3]) == 6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const shapeType = { | |
triangle: new Symbol() | |
}; | |
// Demo func | |
function getArea(shape, options) { | |
var area = 0; | |
switch (shape) { | |
case shapeType.triangle: | |
area = .5 * options.w * options.h; | |
break; | |
} | |
return area; | |
} | |
getArea(shapeType.triangle, {w: 100, h: 50}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function get(url) { | |
return new Promise(function(resolve, reject) { | |
var req = new XMLHttpRequest(); | |
req.open('GET', url); | |
req.setRequestHeader('User-Agent', 'mralexgray'); | |
req.onload = function() { | |
if (req.status == 200) { | |
resolve(JSON.parse(req.response)); | |
} | |
else { | |
reject(Error(req.statusText)); | |
} | |
}; | |
req.onerror = function() { | |
reject(Error("Network Error")); | |
}; | |
req.send(); | |
}); | |
} | |
var params = '?client_id=5d55f8b2c81b86fc413c&client_secret=f816768d68ca421eef677743218db6e768bc93f6'; | |
//ES7 async/await | |
(async function() { | |
let res = await get('https://api.github.com/users/mralexgray/repos' +params) | |
let res2 = await get('https://api.github.com/users/alyssaq/repos' +params) | |
alert('ES7: ' + res[0].full_name + ',\n' + res2[0].full_name) | |
try { | |
let res2 = await get('https://api.github.com/rubbish' +params) | |
//alert('ES7 GOOD: ' + err) | |
} catch (err) { | |
alert('ES7 BAD: ' + err) | |
} | |
}()); | |
//ES6 Promises | |
get('https://api.github.com/users/mralexgray/repos' +params).then(function (res) { | |
get('https://api.github.com/users/alyssaq/repos' +params).then(function (res2) { | |
//alert('ES6: ' + res[0].full_name + ',\n'+ res2[0].full_name) | |
get('https://api.github.com/rubbish' +params).then(function (res3) { | |
//alert('ES6 GOOD: ' + err) | |
}).catch(function (err){ | |
//alert('ES6 BAD: ' + err) | |
}) | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// array utils | |
// ================================================================================================= | |
const combine = (...arrays) => [].concat(...arrays); | |
// combine(["foo"], ["bar", "baz"], [1, 2]) // => ["foo", "bar", "baz", 1, 2] | |
const compact = arr => arr.filter(Boolean); | |
// compact([0, 1, false, 2, "", 3]) // => [1, 2, 3] | |
const contains = (() => Array.prototype.includes | |
? (arr, value) => arr.includes(value) | |
: (arr, value) => arr.some(el => el === value) | |
)(); | |
// contains([1, 2, 3], 3) // => true | |
const difference = (arr, ...others) => { | |
var combined = [].concat(...others) | |
return arr.filter(el => !combined.some(exclude => el === exclude)) | |
}; | |
// difference([1, 2, 3, 4, 5], [5, 2, 10]) // => [1, 3, 4] | |
const head = arr => arr[0]; | |
// head(["foo", "bar"]) // => "foo" | |
const initial = arr => arr.slice(0, -1); | |
// initial([3, 2, 1]) // => [3, 2] | |
const intersection = (...arrays) => | |
[...Set([].concat(...arrays))].filter(toFind => | |
arrays.every(arr => arr.some(el => el === toFind)) | |
); | |
// intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]) // => [1, 2] | |
const last = arr => arr.slice(-1)[0]; | |
// last(["foo", "bar"]) // => "bar" | |
const sortedIndex = (arr, value) => | |
[value].concat(arr).sort().indexOf(value); | |
// sortedIndex([10, 20, 30, 40, 50], 35) // => 3 | |
const tail = arr => arr.slice(1); | |
// tail(["foo", "bar", "baz"]) // => ["bar", "baz" | |
const toArray = (() => Array.from ? Array.from : obj => [].slice.call(obj))(); | |
// Array.isArray((() => toArray(arguments))("foo", "bar")) // => true | |
const union = (...arrays) => [...Set([].concat(...arrays))]; | |
// union([1, 2, 3], [101, 2, 1, 10], [2, 1]) // => [1, 2, 3, 101, 10] | |
const unique = arr => [...Set(arr)]; | |
// unique([1, 2, 1, 3, 1, 4]) // => [1, 2, 3, 4] | |
const without = (arr, ...values) => | |
arr.filter(el => !values.some(exclude => el === exclude)); | |
// object utils | |
// ================================================================================================= | |
const getValues = obj => Object.keys(obj).map(key => obj[key]); | |
const merge = (() => { | |
const extend = Object.assign ? Object.assign : (target, ...sources) => { | |
sources.forEach(source => | |
Object.keys(source).forEach(prop => target[prop] = source[prop]) | |
); | |
return target; | |
}; | |
return (...objects) => extend({}, ...objects); | |
})(); | |
const toMap = (() => { | |
const convert = obj => new Map(Object.keys(obj).map(key => [key, obj[key]])); | |
return obj => obj instanceof Map ? obj : convert(obj); | |
})(); | |
// toMap({ name: "Ben", age: 31 }); // => Map { name: "Ben", age: 31 } | |
// math | |
// ================================================================================================= | |
const min = arr => Math.min(...arr); | |
// min([10, 50, 30]) // => 10 | |
const max = arr => Math.max(...arr); | |
// max([10, 50, 30]) // => 50 | |
const sum = arr => arr.reduce((a, b) => a + b); | |
// sum([1, 2, 3]) // => 6 | |
const product = arr => arr.reduce((a, b) => a * b); | |
// product([2, 5, 10]) // => 100 | |
// function decorators | |
// ================================================================================================= | |
const not = fn => (...args) => !fn(...args); | |
// const isNull = x => x == null; | |
// const isSet = not(isNull); | |
// isSet(undefined); // => false | |
const maybe = fn => | |
(...args) => { | |
if (args.length < fn.length || args.some(arg => arg == null)) return; | |
return fn(...args); | |
}; | |
// var greet = (message, name) => console.log(message + " " + name); | |
// var safeGreet = requireArguments(greet); | |
// greet("Hi"); // => "Hi undefined" | |
// safeGreet("Hi"); // => Doesn't execute | |
const once = fn => { | |
var done = false; | |
return (...args) => { | |
if (done) return; | |
done = true; | |
fn(...args); | |
}; | |
}; | |
// const greet = () => console.log("Hi"); | |
// const greetOnce = once(greet); | |
// greetOnce(); // => "Hi" | |
// greetOnce(); // => Doesn't execute | |
const curry = fn => { | |
const arity = fn.length; | |
const curried = (...args) => | |
args.length < arity ? (...more) => curried(...args, ...more) : fn(...args); | |
return curried; | |
}; | |
// const add = curry((a, b) => a + b); | |
// add(2, 3); // => 5 | |
// add(2)(3); // => 5 | |
const pipeline = (...funcs) => | |
value => funcs.reduce((a, b) => b(a), value); | |
// var plus1 = a => a + 1; | |
// var mult2 = a => a * 2; | |
// var addThenMult = pipeline(plus1, mult2); | |
// addThenMult(5); // => 12 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// See http://www.2ality.com/2014/09/es6-modules-final.html | |
// There are two ways in which you can export things that | |
// are inside the current module: | |
// >>> 1. Mark declarations with the export keyword | |
export let myVar = 'some text'; | |
export const MY_CONST = 42; | |
export class MyClass { } | |
export function myFunc() { } | |
export function* myGeneratorFunc() { } | |
// Note the "operand" of a default export is an expression | |
// (including function expressions and class expressions) | |
export default 123; | |
export default x => x; | |
export default function (x) { return x; }; | |
export default class { | |
constructor(x, y) { | |
this.x = x; | |
this.y = y; | |
} | |
}; | |
// >>> 2. List everything you want to export at the end of the module | |
const MY_CONST = 'HI'; | |
function myFunc() { } | |
export { MY_CONST, myFunc }; | |
// You can also export things under different names | |
export { MY_CONST as THE_CONST, myFunc as theFunc }; | |
// Re-exporting means adding another module’s exports | |
// to those of the current module | |
export * from 'src/other_module'; | |
export { foo, bar } from 'src/other_module'; | |
export { foo as myFoo, bar } from 'src/other_module'; | |
// See http://www.2ality.com/2014/09/es6-modules-final.html | |
// Default exports and named exports | |
import theDefault, { named1, named2 } from 'src/mylib'; | |
import theDefault from 'src/mylib'; | |
import { named1, named2 } from 'src/mylib'; | |
// Renaming: import named1 as myNamed1 | |
import { named1 as myNamed1, named2 } from 'src/mylib'; | |
// Importing the module as an object | |
// (with one property per named export) | |
import * as mylib from 'src/mylib'; | |
// Only load the module, don’t import anything | |
import 'src/mylib'; | |
// When using module name mapping e.g. JSPM | |
import $ from 'jquery'; | |
import _ from 'lodash'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// So we define a function that loads images, and returns a promise for us to listen to | |
function loadImages(images){ | |
//alert(blah); //promise should catch on this error here | |
// We can take advantage of `map` which iterates through an array and makes an array | |
// out of the returns of each iteration. In this case, we return a promise for each | |
// url, for `Promise.all` to listen to later. | |
var promises = images.map(function(url){ | |
// Create a Deferred object and image, and handle the resolution stuff. | |
var deferred = Promise.defer(); | |
var image = new Image(); | |
image.onload = function(){deferred.resolve('image success: '+ url);}; | |
image.onerror = function(){deferred.reject('image failed: ' + url);}; | |
image.onabort = function(){deferred.reject('image aborted: ' + url);}; | |
image.src = url; | |
// Return the promise, which will be stored in the array, thanks to `map` | |
return deferred.promise; | |
}); | |
// Listen on the array of promises (aha moment: jQuery.when == Promises.all, more or less.) | |
return Promise.all(promises); | |
} | |
// Now we use `loadImages`, loading an array of urls, and listening for notices | |
loadImages([ | |
'http://www.mozilla.org/media/img/firefox/favicon.png', | |
'https://developer.cdn.mozilla.net/media/redesign/img/favicon32.png' | |
]).then(function(value){ | |
console.log('loadImages successful: ' + value); | |
},function(error){ | |
console.log('loadImages failed: ' + error); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// With comments: | |
function promiseSome(promises) { | |
// We're going to 'sort' promises into fulfilled & rejected values | |
var fulfills = []; | |
var rejects = []; | |
// Using reduce to create a promise chain | |
return promises.reduce(function(chain, promise) { | |
// Wait for the last in the chain | |
return chain.then(function() { | |
// Wait for the current in the chain. | |
// This has a nice side effect that it deals with values | |
// in `promises` that are simple values rather than promises | |
return promise; | |
}).then(function(val) { | |
// Store the success value | |
fulfills.push(val); | |
}, function(err) { | |
// Store the failure | |
// This also 'handles' the error in terms of the chain, | |
// so the chain always fulfills with undefined | |
rejects.push(err); | |
}); | |
}, Promise.resolve()).then(function() { | |
// Reject only if nothing fulfilled | |
if (!fulfills[0]) throw Error("All failed"); | |
return fulfills; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment