New Shiny

New syntax and
operators

  • const, let, for...of
  • Default arguments
  • Fat arrow

But wait! there is more.

  • Template literals
  • Map and Set
  • New Object literals syntax
  • Rest and spread operators

Problem

Be nice to indicate that a variabled is a constant.

const


const LIGHT_SPEED = 299792458;

// TypeError: Assignment to constant variable.
LIGHT_SPEED = 300;

/*Stil 299792458*/
LIGHT_SPEED;

//throws TypeError: redeclaration of const
const 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);
        

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))

Fat arrow


fatArrow = (params) => { statements }
          

Knitted Hello Kitty Dissection by estonia76

Fun rules to remember:

  • 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  (LOLWUT?)
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

Tagged strings (HTML`...`).

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();

WeakMap and WeakSet

  • Memory management

Problem

Creating object literals is cumbersome.

Today


function makeTruck(make){
  return {
    make: make,
    drive: function(){
      return "Driving!"
    }
  };
}

Enhanced properties


function makeTruck(make){
  return {
    make,
    drive() {
      return "Driving!"
    }
  };
}

Problem

Extracting properties from objects/arrays leads to redundant code.

Today


var people = [
  ["Bob", "S", "Smith"],
  ["Mary", "W", "Smith"],
];

var objects = people.map((person) => {
  var firstName = person[0];
  var lastName = person[2];
  return {
    firstName,
    lastName,
  };
});
        

Array matching


var people = [
  ["Bob", "S", "Smith"],
  ["Mary", "W", "Smith"],
];
// We name the positions into variables
var objects = people
  // Note we assigning names in
  // the function's arguments!
  .map(
    ([firstName, , lastName])
      => ({firstName, lastName})
  );

Manually destructuring objects


var person = {
  firstName: "Mary",
  middleInitial: "S",
  lastName: "Smith",
  address: "123 JS Street",
};

var firstName = person.firstName;
var middleInitial = person.lastName;
var lastName = person.middleInitial;

Destructuring assignment


var person = {
  firstName: "Mary",
  middleInitial: "S",
  lastName: "Smith",
  address: "123 JS Street",
};

const {
  firstName,
  lastName,
  middleInitial
} = person;

Destructuring assignment - take 2


var person = {
  firstName: "Mary",
  middleInitial: "S",
  lastName: "Smith",
  address: "123 JS Street",
};

const {
  firstName: first,
  lastName: last,
  middleInitial: middle
} = person;

Destructuring assignment - functions


var person = {
  firstName: "Mary",
  middleInitial: "S",
  lastName: "Smith",
  address: "123 JS Street",
};

function x({firstName: f, lastName: l}) {
  return [f, l];
}

Destructuring assignment - deep matching


var person = {
  firstName: "Mary",
  address: {
    street:"123 JS Street"
  },
};

function x({firstName: f, address: {street}}) {
  return [f, street];
}

Problem

Making functions with open-ended arguments is hard

Rest and spread


var cookieMonster = {
  whatIAte: [],
  eat(){
    for(let cookies of arguments){
      this.cookies.push(cookie);
    }
  }
}

Rest and spread


var cookieMonster = {
  whatIAte: [],
  eat(...cookies){
    //push is "variadic"
    this.whatIAte.push(...cookies);
  },
}

Rest and spread


function namedFunction(first, second, ...theRest){
  console.log(first, second, theRest);
}
namedFunction(1); //1, undefined, []
namedFunction(1, 2); //1, 2, []
namedFunction(1, 2, 3, 4); //1, 2, [3, 4]

Great Resources

Thanks! Questions?