Proposals
- Code styleguide
- ES6: New features
- ES6 Overview in 350 bullet points!!!
- JavaScript Modules
- ES6 Modules: The Final Syntax
- CoreJS
- Exploring ES6
- TC39 ECMA262 status and process
- Babel 5.0 released on March 2015
- ES6 Features
- .eslintrc example
- Another .eslintrc example
- Eric Elliott's eslintrc example
- Babel call for contributors
- eslint-config-strict
- The Boolean Trap
- JS Rocks
- React on ES6+
- Why Babel Matters
- Function Bind
- Elegant React with ES6
- Functions without "function"
- super() considered hmmm-ful
Tools
indexOf uses Strict Equality Comparison. See SameValueZero comparison.
Objects in JavaScript have reference equality.
{error: error} === {error}
String.prototype.includes
String.prototype.startsWith(txt, start)
String.prototype.endsWith(txt, end)
String.prototype.repeat(count)
String.prototype.trim()class Radio {}
export { Radio as Player };
import { Player as SportsPlayer } from 'radio';
var basketball = new SportsPlayer();CJS and AMD can only export one thing. Historically, we've worked around that by exporting an object with lots of things - for example, Underscore exports the _ object with lots of functions attached:
var _ = {
where: fn,
memoize: fn,
pluck: fn
};This single export make it hard to do tree-shaking and choose only the right amount of modules to bundle to decrease file size.
Class, unlike function is not hoisted, so you have to declared it before using it.
You have to call super before you can use access this.
- How to use classes and sleep at night
- Not Awesome: ES6 Classes
- JavaScript Factory Functions vs Constructor Functions vs Classes
Can be a security concern if you allow user to input template string.
if (x > y) {
var tmp = x;
x = y;
y = tmp;
}
console.log(tmp === x); // true
if (x > y) {
let tmp = x;
x = y;
y = tmp;
}
console.log(tmp === x); // ReferenceError: tmp is not definedExtract data from arrays or objects using syntax that "mirrors" the construction of array and object literals.
// Array destructuring
let [x, y] = ['a', 'b']; //=> x=a, y=b
let [x, y, ...rest] = ['a', 'b', 'c', 'd']; //=> rest = ['c', 'd']
[x, y] = [y, x]; // swap values// Object destructuring
var o = {p: 42, q: true};
var {p, q} = o; // Means o.p and o.q
const { visible, className, tag } = this.props
let { city: c, state: s } = getAddress(); //=> c will be obj.city
// Can also used in function with default value
function random({ min=1, max=200 } = {}) {
return Math.floor(Math.random() * (max - min)) + min;
}
// Rest Properties
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }// Destructuring in module loading
const {clone, assign} = require('lodash'); // Means _.clone and _.assign
function makeRequest(url, method, params) {
var config = {url, method, params};
// Same as
var config = {
url: url,
method: method,
params: params
}
}A better apply and a better push.
// Easier concatenation
[1, 2, ...[3, 4, 5], 6, 7]Can be used for destructuring also.
[..."abc"] // Will become [ 'a', 'b', 'c' ]
[...document.querySelectorAll('div')] // Same, will give you [<div>, <div>, <div>]
// Which is a better apply, because console.log() function take in argument with comma
console.log(...[1, 2, 3])
var a = [1, 2, 3];
var b = [...a, 4, 5];
// For destructuring
var a, b, c;
[a, b, ...c] = [1, 2, 3, 4, 5];
// With function
function bar(a, b, c) {
}
var args = [1, 2, 3];
bar(...args);
function bar(a, ...params) {
}
// Spread Properties
let n = { x, y, ...z }
n; // { x: 1, y: 2, a: 3, b: 4 }
// Unknown props example
// See https://facebook.github.io/react/warnings/unknown-prop.html
function MyDiv(props) {
// We filter out the layout property
const { layout, ...rest } = props;
return <div {...rest} style="demo">Test</div>
}// Making a shallow copy
let copy = { ...original }
// Merge several different objects
let merged = { ...foo, ...bar, ...baz }
// Add new properties in the process of merging
let newObj = {
title: 'hello',
...foo,
world: 200,
...bar
}Object rests are the dual of object spreads, in that they can extract any extra properties that don't get picked up when destructuring an element.
// If you want to remove irrelevant props
render() {
switch(this.props.size) {
// do something with size prop
}
var attrs = Object.assign({}, this.props); // shallow clone
delete attrs.size;
return <a {...attrs}>{this.props.children}</a>;
}
// Or you can use ES7
render() {
var {size, ...attrs} = this.props;
switch(this.props.size) {
// do something with size prop
}
return <a {...attrs}>{this.props.children}</a>;
}
//
deleteComment(comment) {
$.ajax.delete(comment);
// clone using spread operator
const comments = [...this.state.comments];
const commentIndex = comments.indexOf(comment);
comments.splice(commentIndex, 1);
this.setState({ comments });
}<Something {...propsA} propB="B" />
// Spread attributes actually use Object.assign
React.createElement(Something, Object.assign({}, propsA, {propB: 'B'}))var a = Object.keys(toggleStates).reduce((newStates, key) => {
newStates[key] = !toggleAll;
return newStates;
}, {});
// Same as
var six = [1, 2, 3].reduce((sum, n) => {
return sum + n;
}, 0);- Exploring ES2016 Decorators
- Real Mixins with JavaScript Classes
- Using ES.later Decorators as Mixins
- Method Advice
- mixwith.js
- Command Pattern
Mixin is just metaobject?
Mixin application should create a new class (metaclass) by composing existing ones.
import React from 'react';
import autobind from 'autobind-decorator';
let { PropTypes, Component } = React;
@autobind
class Person extends Component {
// Use constructor instead of componentWillMount()
constructor(...args) {
super(...args);
// No more getInitialState
this.state = {
name: props.name
};
// If you do not want to use ES8 to bind event
this.handleClick = this.handleClick.bind(this)
}
// ES7 property initializers
state = { isEditing: false };
static defaultProps = { initialCount: 0 };
static propTypes = {
user: React.PropTypes.object.isRequired
}
// ES8 - Good for event handler and callback which need binding
// See https://daveceddia.com/avoid-bind-when-passing-props/
change = env => this.setState({isEditing: true});
// Combining 2 features: Arrow function + property initializers
handleClick = (e) => this.setState()
setName(name) {
this.setState({ name: name });
}
handleChange(name, e) {
var newState = {};
newState[name] = e.target.value;
this.setState(newState);
// Or you can
this.setState({
[name]: e.target.value
});
}
render() {
return();
}
}
// ES6, not ES7
Person.propTypes = {
items: PropTypes.array.isRequired
};
// No more getDefaultProps
Person.defaultProps = { name: 'anonymous' };
export default Person;A generator is basically a function whose execution can be paused and then resumed later, remembering its state.
ES7 introduce the async and await keywords, removing the need for a generator library altogether.
Generators don't have to terminate which make it very useful.
function *myGen(x) {
yield x;
}
var iterator = myGen();
iterator.next();
// Using Alt.js
async login(data) {
try {
const response = await axios.post('/login', data);
this.dispatch({ok: true, user: response.data});
} catch (err) {
this.dispatch({ok: false, error: err.data});
}
}Function.prototype.apply.call(f, obj, args);
Reflect.apply(f, obj, args);