function f() {
{
let x;
{
// this is ok since it's a block scoped name
const x = 'sneaky';
// error, was just defined with `const` above
x = 'foo';
}
// this is ok since it was declared with `let`
x = 'bar';
// error, already declared above in this block
let x = 'inner';
}
}
for (var i of [1,2,3]){
setTimeout(()=>console.log(i),0)
}
// vs.
for (let i of [1,2,3]){
setTimeout(()=>console.log(i),0)
}
for (let i of [1,2,3]){
setTimeout(()=>console.log(i),0)
}
// would be in ES5 sth like:
for (var i of [1,2,3]){
((index) => setTimeout(()=>console.log(index),0))(i)
}
const obj = {
// Sets the prototype.
__proto__: theProtoObj,
// Shorthand for 'handler: handler'
handler,
// Methods
toString() {
// Super calls
return 'd ' + super.toString();
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
};
// Basic literal string creation
`This is a pretty little template string.`
// Multiline strings
`In ES5 this is
not legal.`
// Interpolate variable bindings
const name = 'Bob', time = 'today';
`Hello ${name}, how are you ${time}?`
// Unescaped template strings
String.raw`In ES5 "\n" is a line-feed.`
// Expression bodies
const incr = [1,2,3].map(v => v + 1);
const nums = [1,2,3].map((v, i) => v + i);
// Statement bodies
nums.forEach(v => {
if (v % 5 === 0)
console.log(v);
});
const bob = {
_name: 'Bob',
_friends: ['Anna'],
printFriends() {
this._friends.forEach(f =>
console.log(`${this._name} knows ${f}`)
);
}
};
function f(x, y, z) {
return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) === 6 // true
const g = (x, ...y) => {
// y is an Array
return x * y.length;
}
g(3, 'hello', true) === 6 // true
// arrays
const [a, ,b] = [1,2,3];
const [a, ...b] = [1,2,3];
// objects
const {documentElement, ...other} = document;
console.log(documentElement);
console.log(other.location);
// Fail-soft destructuring with defaults
const [a = 1] = [];
a === 1;
// Object.assign alternative
{...{a: 'a', b:2, c:3}, ...{b:100, d: 'd'}}
const f = (x, y = 12) => {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
f(3) === 15 // true
// with destructuring
const f = ({x:alias = 1, y = 12} = {}) => {
return alias + y;
}
const 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) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}
const fibonacci = {
[Symbol.iterator]: function*() {
var pre = 0, cur = 1;
for (;;) {
[pre, cur] = [cur, pre + cur];
yield cur;
}
}
}
// lib/math.js
export function sum(x, y) {
return x + y;
}
export const pi = 3.141593;
// app.js
import * as math from "lib/math";
console.log(`2π = ${math.sum(math.pi, math.pi)}`);
// otherApp.js
import {sum, pi} from "lib/math";
console.log(`2π = ${sum(pi, pi)}`);
// i.do.not.like.default.export.js
export default function(x) {
return Math.exp(x);
}
// Sets
const s = new Set();
s.add('hello').add('goodbye').add('hello');
s.size === 2;
s.has('hello') === true;
// Maps
const m = new Map();
m.set('hello', 42);
m.set(s, 34);
m.get(s) == 34;
// Weak Maps
const wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
// Weak Sets
const ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references,
// it will not be held in the set
// Proxying a normal object
const target = {};
const handler = {
get: function (receiver, name) {
return `Hello, ${name}!`;
}
};
const p = new Proxy(target, handler);
p.world === 'Hello, world!';
const target = function () { return 'I am the target'; };
const handler = {
apply: function (receiver, ...args) {
return `I am the proxy -> ${receiver()}`;
}
};
const p = new Proxy(target, handler);
p(); // "I am the proxy -> I am the target"
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);
this.idMatrix = SkinnedMesh.defaultMatrix();
this.bones = [];
this.boneMatrices = [];
//...
}
update(camera) {
//...
super.update();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}
function timeout(duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
})
}
const p = timeout(1000).then(() => {
return timeout(2000);
}).then(() => {
throw new Error('hmm');
}).catch(err => Promise.all([
timeout(100).then(()=>100),
timeout(200).then(()=>200)
])
).then(console.log)
async function timeout(duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
})
}
await timeout(1000);
await timeout(2000);
try {
throw new Error('hmm');
} catch (err) {
const data = await Promise.all([
timeout(100).then(()=>100),
timeout(200).then(()=>200)
]);
console.log(data);
}
async saveUser({
upsert = true,
transaction,
...userInfo
}) {
// save to the DB
return {
operation, // e.g 'INSERT'
status, // e.g. 'Success'
saved: userInfo
}
}
const arr = [1,2,3,4,5,6,7,8,9]
function getOdds(arr) {
let odds = []
for(let i = 0; i < arr.length; i++) {
if( i % 2 !== 0) {
odds.push(i)
}
}
return odds
}
console.log(getOdds(arr))
// logs [1, 3, 5, 7, 9]
function getOdds(arr) {
return arr.filter(num => num % 2 !== 0)
}
console.log(getOdds(arr))
// logs [1, 3, 5, 7, 9]
//even shorter
const getOdds2 = arr => arr.filter(num => num % 2 !== 0)
function add(x) {
return function add(y) {
return x + y
}
}
// better
const add = x =>
y =>
x + y
console.log(add(3)(4)) // 7
const add3 = add(3)
console.log(add3(4)) // 7
console.log(add3(5)) // 8
const createDivideFilter = divFactor =>
x =>
(x % divFactor===0)
([...Array(20)].map((v, i) => i).filter(createDivideFilter(2)))
// [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ]
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
class HelloWorld extends Component {
render() {
return (
<div className="hello">
Hello World
</div>
);
}
}
// usage example: <HelloWorld/>
const element = (
Hello, World!
)
// Babel compiles it to
const element = React.createElement(
'h1',
{className: 'hello'},
'Hello, World!'
)
export class App extends Component {
world = 'World';
render() {
return (
<div className="book-app">
<Hello who={this.world} />
</div>
);
}
}
export class Hello extends Component {
render() {
const { who } = this.props;
return <span className="hello">Hello {who}</span>;
}
}
Props are read only!
export class Hello extends Component {
constructor(props) {
super(props);
this.state = {
who: props.who,
};
}
onWhoChange(e) {
e.preventDefault();
this.setState({
who: e.target.value,
});
}
render() {
const { who } = this.state;
return (
<div className="hello-container">
<span className="hello">Hello {who}</span>
<input value={who}
type="text"
onChange={(e) => this.onWhoChange(e)}
/>
</div>
);
}
}
export class Hello extends Component {
state = {
who: this.props.who,
}
onWhoChange = e => {
e.preventDefault()
const who = e.target.value
this.setState((prevState, props) => ({
who,
}));
}
render() {
const { who } = this.state;
return (
<div className="hello-container">
<span className="hello">Hello {who}</span>
<input value={who}
type="text"
onChange={this.onWhoChange}
/>
</div>
);
}
}
class Hello extends Component {
state = {
who: this.props.who,
};
onWhoChange = (e) => {
e.preventDefault();
const who = e.target.value;
this.setState((prevState, props) => ({
who,
}));
}
render() {
const { who } = this.state;
return (
<DumbHello who={who} onWhoChange={this.onWhoChange} />
);
}
}
const DumbHello = ({ who, onWhoChange }) => (
Hello {who}
);
const element = () => (
Hello World
)
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
}
{
type: 'ADD_TODO',
text: 'Go to swimming pool'
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }])
default:
return state
}
}
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}, {
text: 'Go to swimming pool',
completed: false
}],
}