Be nice to indicate that a variabled is a constant.
const
//meters per second (c in e=mc2)
const LIGHT_SPEED = 299792458;
/*ignored (not an exception!)*/
LIGHT_SPEED = 300;
/*Stil 299792458*/
LIGHT_SPEED;
Problem
Be nice to not leak variables all over the place.
var object = {ohhai: "value"}
for(var i in object){
var item = object[i];
}
console.log(i); // "ohhai", that's annoying.
console.log(item); //"value", argh.
let
let fruits = ["apple", "orange"]
//keep it in the loop
for(let i=0; i < fruits.length; i++){
let fruit = fruits[i];
}
//Reference error: no `fruit` or `i` here!
console.log(fruit, i);
var fruit = "apple",
juice = "";
{
let veg = "carrot"
juice = veg + " " + fruit;
}
console.log(juice) //"carrot apple"
veg; //error, not defined!
Problem
Having to check if a value was passed to a method... is annoying !
//Today... life is hard
function myFunction(arg1){
var arg1 = arg1 || "some thing";
}
Default argument
function Car(
make = "ford",
model = "t"){
this.make = make;
this.model = model;
}
let car = new Car();
//prints "ford"
console.log(car.make);
Problem
for loop syntax is annoying.
//Today... life is hard
var h1s = document.querySelectorAll("h1");
for(var i = 0; i < h1s.length; i++){
var elem = h1s[i]
elem.style.color = "salmon";
};
//Or, the unexpected
for(var elem in h1s){
//"length and item?!?!" ERROR!!
elem.style.color = "salmon";
}
for ... of (iterators)
var h1s = document.querySelectorAll("h1");
for(let elem of h1s){
elem.style.color = "salmon";
}
Problem
Having to write function all the time causes
carpal tunnel syndrome.
//today
function findEdible(fruits){
return fruits.filter(function(item){
return /^a/.test(item);
});
}
var fruits = ['apple','orange','apricot'];
//Array [ "apple", "apricot" ]
console.log(findEdible(fruits))
If you have 1 argument, paranthesis "()" are optional.
If you have 1 statement, the "{}" are optional.
If you have 1 statement, "return" is optional.
//long form
var multiply = (x,y) => {
const z = 1;
return x * y * z;
};
multiply(2,3); //6
//omitting optional bits
var square = x => x * x;
square(3); //9
var fruits = ['apple','orange','apricot'];
var edible = fruits.filter(
item => /^a/.test(item)
);
Careful! scope of this
function Car (){
this.speed = 0;
}
Car.prototype.drive = (newSpeed) => {
this.speed = newSpeed;
}
var car = new Car();
car.drive(1000);
//prints: 0 (WTF?)
console.log(car.speed);
console.log(window.speed); //1000
Problem
String concatenation is repetitive and annoying.
var data = [{name:"a",link:"page.html"}]
function processData(data){
var ul = "<ul>";
for (var i = 0; i < data.length; i++) {
var item = data[i];
var li = '<li><a href="' + item.link;
li += '">' + item.name;
li += '</a><li>\n';
ul += li;
};
ul += "</ul>";
return ul;
}
processData(data);
Template strings
Meet ` and ${}
var data = [{name:"a",link:"page.html"}]
function processData(data){
var listItems = "";
for (let item of data) {
let li = `
<li>
<a href="${item.link}">
${item.name}
</a>
</li>`;
listItems += li;
};
return `<ul>${listItems}</ul>`;
}
processData(data);
Security
Safe strings coming soon (safehtml`...`).
Problem
It's hard to create a collection of unique things.
Sets
var fruits = new Set(["apple",
"orange", "orange",
"pear"]);
fruits.has("banana"); //false
fruits.add("banana");
fruits.add("banana"); //ignored
fruits.size; //4
fruits.delete("apple");
for(let fruit of fruits){ /*fruit*/ };
fruits.clear(); //empty the set
Problem
Hey! What about key/value pairs !?
Maps
let store = new Map([["socks",
{amount: 5, cost: 10}
]]);
store.set("shoes",{amount:5,cost:99.99});
store.has("socks"); //true
for(let item of store){ /*item is array*/ }
for(let key of store.keys()){ }
store.clear();
var p1 = Promise.resolve("fulfilled!");
p1.then((msg)=>console.log(msg));
var p2 = Promise.reject("rejected!");
p2.then(undefined, (msg)=>console.log(msg));
var p3 = new Promise((resolve,reject)=>{
if (condition) resolve();
if (otherCondition) reject();
throw new Error("Error!")
});
//fulfill, reject, catch
p3.then(()=>{},()=>{})
.catch(()=>{});
var barista = {
skills: new Set(['Americano','Latte']),
get mood(){return Math.round(Math.random())},
makeCoffee(type = 'Americano') {
if (!this.skills.has(type)){
let msg = `No ${type} for you!`;
return Promise.reject(msg);
}
return new Promise((resolve, reject)=>{
//1 second to make a coffee
setTimeout(()=>{
(this.mood) ?
resolve(`Here is your ${type}`)
: reject("I quit!");
}, 1000);
});
}
}
var success = msg => console.log(msg, "thanks!"),
fail = err => console.log(err);
//reject straight away!
barista.makeCoffee("milkshake").then(undefined, fail);
//Make me an Americano and a latte
barista.makeCoffee()
.then(() => barista.makeCoffee("Latte"))
.then(success).catch(fail);
Problem
Hard to represent dynamic infinite or finite sequences.
function* electricityGenerator(fuel=0){
//while we have fuel
while(fuel){
//HALT!
yield `spark! ${fuel--}`;
}
}
var gen = electricityGenerator(10);
//it's just an iterator!
for(let electricity of gen){
//prints "spark N!" 10 times
console.log(electricity);
}
Hand-cranking with .next()
var gen = electricityGenerator(10);
var next = gen.next();
// Object { value: value || undefined ,
// done: true || false }