On Github maxpou-slides / js-today-2017
Maxence POUTORD
// const const url = "www.hostelworld.com" url = "http://www.hostelworld.com" // Uncaught TypeError: Assignment to constant variable const url = "www.hostelworld.com" // Identifier 'url' has already been declared // let let url = "www.hostelworld.com" url = "http://www.hostelworld.com/" // ok let url = "https://www.hostelworld.com" // Uncaught SyntaxError: Identifier 'url' has already been declared // var var url = "www.hostelworld.com" url = "http://www.hostelworld.com/" // ok var url = "https://www.hostelworld.com" // ok
ES5:
var fruit = ["apple", "banana", "kiwi"]
var fruitUpperCase = fruit.map(function (f) {
return f.toUpperCase()
})
ES6:
const fruit = ["apple", "banana", "kiwi"]
const fruitUpperCase = fruit.map(f => {
return f.toUpperCase()
})// or better:
const fruitUpperCase = fruit.map(f => f.toUpperCase())
// JS is synchronous
setTimeout(() => console.log('a'), 500)
setTimeout(() => console.log('b'), 50)
setTimeout(() => console.log('c'), 23)
setTimeout(() => console.log('d'), 600)
setTimeout(() => console.log('e'), 10)function sleep (ms) {
return new Promise(r => setTimeout(r, ms))
}// asynchronous calls
sleep(2500)
.then(() => {
console.log('a')
})
.then(sleep(50))
.then(() => {
console.log('b')
})
.then(sleep(1000))
.then(() => {
console.log('c')
})
const hostel = { name: "Happy hostel", price: 12.5, stars: 4.5 }
// es5
var html = "<h1>" + hostel.name + "</h1>"
html += "<span class="price">" + hostel.price + "€</span>"
html += "<span class="stars">" + hostel.stars + "</span>"// es6
const html = `
<h1>${hostel.name}</h1>
<span class="price">${hostel.price}€</span>
<span class="stars">${hostel.stars}</span>
`
const params = [ "hello", true, 7 ] const other = [ 1, 2, ...params ] // [ 1, 2, "hello", true, 7 ]
var number = 2
function incrementBy (increment) {
launchNuclearMissile()
return number + increment
}
function increment (number, increment) {
return number + increment
}
var properties = [{/* */}]
for (var i = 0; i < properties.length; i++) {
properties[i].image = properties[i].image.replace(/^http:\/\//i, 'https://')
properties[i].price = properties[i].price + "€"
}
const properties = [{/* */}]
const formattedProperties = properties.map(property => {
property.image = property.image.replace(/^http:\/\//i, 'https://')
property.price = property.price + "€"
return property
})
const property = {
id: 23,
name: 'happy hostel'
}
property.name = 'highjack'
With const, only reference is read only. You can still update the value.
Benefits: a better segregation in the code
// Imperative
function printProperties (properties) {
for (var i = 0; i < properties.length; i++) {
properties[i] = properties[i].name + ", " + properties[i].city
}
return properties
}
This function have 2 differents behaviors
// Declarative way
function printProperties (properties) {
return properties.map(p => p.name + ", " + p.city)
}
var highRatedProperties = []
for (property of properties) {
if (property.rate >= 70) {
highRatedProperties.push(property)
}
}const highRatedProperties = properties.filter(property => property.rate >= 70)
const sumRate = properties.reduce((accumulator, current) => accumulator + current.rate, 0); const averageRate = sumRate / properties.length;
const formatedHighRatedProperties = properties .filter(p => p.rate >= 70 || p.isNew) .map(p => p.name + ", " + p.city) .sort((a, b) => b.rate - a.rate)
Map/filter/reduce in a tweet:map([🌽, 🐮, 🐔], cook)=> [🍿, 🍔, 🍳]filter([🍿, 🍔, 🍳], isVegetarian)=> [🍿, 🍳]reduce([🍿, 🍳], eat)=> 💩
— Steven Luscher (@steveluscher) 10 juin 2016<div id="app">
<ul>
<fruit-item v-for="fruit in fruits" v-bind:fruit="fruit"></fruit-item>
</ul>
<change-fruit-button v-on:change="changedata($event)"></change-fruit-button>
</div>
Vue.component('fruit-item', {
props: ['fruit'],
template: `<li>{{ fruit }}</li>`
})
Vue.component('change-fruit-button', {
template: `<button v-on:click="changeFruit">Change!</button>`,
methods: {
changeFruit: function () {
this.$emit('change', ['pear', 'peach', 'cranberry'])
}
}
})
new Vue({
el: '#app',
data: {
fruits: ['banana', 'apple', 'kiwi']
},
methods: {
changedata: function (newdata) {
this.fruits = newdata
}
}
})
Package Manager (surch as Composer)
{
"name": "js-today",
"version": "1.0.0",
"author": "Maxence POUTORD <github@maxpou.fr>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/maxpou-slides/js-today"
},
"main": "app.js",
"scripts": {
"start": "node_modules/http-server/bin/http-server",
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint ."
},
"devDependencies": {
"eslint": "^3.12.2",
"http-server": "^0.9.0"
}
}
</github@maxpou.fr>
Transform es2015+ to ES5
// beatiful es6
[1,2,3,4,5]
.filter(n => n % 2 === 0)
.map(n => n + 1)
// ugly es5
[1, 2, 3, 4, 5].filter(function (n) {
return n % 2 === 0;
}).map(function (n) {
return n + 1;
});
Linter for Javascript
/Users/maxence.poutord/sites/lab/whatever.js 8:6 error 'test' is assigned a value but never used no-unused-vars 10:5 error Unexpected console statement no-console 16:26 error Missing semicolon semi ✖ 3 problem (3 error, 0 warnings)