For explanation see video https://www.youtube.com/watch?v=Jakoi0G8lBg

log = console.log

for (c of 'abc') {
   log(`${c},`)
}

let sum = (a = 1, b = 2) => a + b;
log(sum()); // 3

let templit = (strs, ...vals) => {
  for(s of strs) {
     log(`Str: "${s}"`)
  }
  for(v of vals) {
     log(`val: "${v}"`)
  }
};
//templit `abc ${1} def ${2}`;
//Str: "abc "
//Str: " def "
//Str: ""
//val: "1"
//val: "2"

'Abc'.startsWith('Ab') //true
'Abc'.endsWith('Ab') //false
'Abcedf'.includes('ed') //true
'e'.repeat(2) //ee

[1,2,3,4,5].reduce((a, b) => a + b) // 15

[1,2,3,4,5].filter((a) => a % 2 === 0) //[2, 4]

[1,2,3,].map((v) => v * 2) // [2, 4, 6]

Objects and Classes

"Functional" object (not ES6 related):

function obj (param) {
  let o = {
     param,
     printInternalParam() {
        log(`Internal param: ${this.param}`);
     }
  }
  return {
    getParam() {
       o.printInternalParam();
       return `${o.param}`
    }
  }
}
obj(1).getParam()
//Internal param: 1
//"1"
Object.getOwnPropertyNames(obj(1)) // getParam

// grep attributes from object
let o = obj(2);
let { getParam } = o;
getParam(); //2

let [, ...last2] = [1,2,3]
log(last2) //[2, 3]

Classes :

class Cla {
  constructor (name) {
    this._n = name;
  }

  get name() {
    return this._n;
  }

  set name(name) {
    this._n = name;
  }

  static new(name) {
   return new Cla(name);
  }
}

cla = Cla.new('foo');
cla.name = 'bar';
log(cla.name)


class Child extends Cla {
  constructor(name, brandNewParam) {
   super(name);
   log(brandNewParam)
  }
}


let cap = Symbol("State cap");
let pensyl = {}
pensyl[cap] = "Harrisburg"
log(pensyl[cap])

let pensyl2 = {
  cap: "Harrisburg"
}
log(pensyl2[cap]) // undefined!

Arrays, Sets, Maps

Array.of(1,2,3) //  [1, 2, 3]
Array.from("abc") //["a", "b", "c"]
Array.from([1,2,3], (a) => a*2) //[2, 4, 6]

let s = new Set()
s.add(1);
s.add('wo');
log(s.has(1)) // true
log(s.size);
s.delete(10);
for(v of s){ log(`Set val ${v}`) }


let m = new Map();

m.set('k1', 1);
m.set('k2', 2);

log(m.get('k1'));
log(m.size);

m.forEach((val, key) => {
 log(`key${key}: val${val}`)
})

Promises

let p = Promise.resolve("Resolve ME");
p.then( (res) => log(res) );

let p3 = new Promise( (resolve, reject) => {
  setTimeout( () => resolve('2 sec passed'), 2e3);
  setTimeout( () => throw new Error('4 sec passed'), 4e3);
});
p3.then( (res) => log(`resolved: ${res}`) ).catch(
(res) => log(`rejected: ${res}`) );