Modern 

 VAR vs LET

let x = 10;
if (x === 10) {
    let x = 20;
    console.log(x); // 20
}
console.log(x); // 10
  • The var keyword allows you to redeclare a variable without any issue
  • The var variables belong to the global scope or local scope
  • let variables are blocked scopes
  • If you redeclare a variable with the let keyword, you will get an error
var counter = 0;
console.log(window.counter); //  0
let counter = 0;
console.log(window.counter); // undefined
var x = 10;
if (x === 10) {
    var x = 20;
    console.log(x); // 20
}
console.log(x); // 20
let counter = 10;
let counter; // error
var counter = 10;
var counter;
console.log(counter); // 10

DON'T USE VAR

CONST

const person = { age: 20 };
person.age = 30; // OK
console.log(person.age); // 30
person = {age: 40}; // TypeError

The const keyword creates a read-only reference to a value.

const person = Object.freeze({age: 20});
person.age = 30; // nothing happens
const RED; // SyntaxError
const RATE = 0.1;
RATE = 0.2; // TypeError
const company = Object.freeze({
    address: Object.freeze({
        street: 'North 1st street',
        city: 'San Jose',
    })
});


company.address.country = 'USA'; // OK

Template Literals

  • Multiline string: a string that can span multiple lines

  • String formatting: the ability to substitute part of the string for the values of variables or expressions. This feature is also called string interpolation

let simple = `This is a template literal`;
let p =
`This text
can
span multiple lines`;
let firstName = 'John',
    lastName = 'Doe';

let greeting = `Hi ${firstName}, ${lastName}`;
console.log(greeting); // Hi John, Doe
let price = 8.99,
    tax = 0.1;

var netPrice = `Net Price:$${(price * (1 + tax)).toFixed(2)}`;

console.log(netPrice); // netPrice:$9.89

Spread operator

const odd = [1,3,5];
const combined = [2,4,6, ...odd];
console.log(combined); // [ 2, 4, 6, 1, 3, 5 ]

The spread operator allows you to spread out elements of an iterable object such as an array, a  map, or a set.

Constructing array literal

const initialChars = ['A', 'B'];
const chars = [...initialChars, 'C', 'D'];
console.log(chars); // ["A", "B", "C", "D"]

Concatenating arrays

Copying arrays

 

let numbers = [1, 2];
let moreNumbers = [3, 4];
let allNumbers = [...numbers, ...moreNumbers];
console.log(allNumbers); // [1, 2, 3, 4]
let scores = [80, 70, 90];
let copiedScores = [...scores];
console.log(copiedScores); // [80, 70, 90]

spread operator

const person = {
    name: 'Zé',
};
// {name: "Zé"}

const otherPerson = {
  ...person,
  lastName: 'Maria',
}
// {name: "Zé", lastName: "Maria"}

Copying Objects

let chars = ['A', ...'BC', 'D'];
console.log(chars); // ["A", "B", "C", "D"]

spread operator and strings

The spread operator can also be used to clone objects into one.

Deep Copy vs Shallow Copy

Keep in mind the above creates a shallow clone of the array. They clone the array itself, but not the array elements, the same happens to objects.

This difference doesn't matter when you have an array of primitives (numbers, strings, null, undefined), but it does when you have an array of objects.

const arr = [{ answer: 42 }];

const arr2 = [...arr];
arr2[0].answer = 0;

// `0`, because `arr[0]` is a reference to the same object as `arr2[0]`
arr[0].answer;

Destructuring

 Allows you to destructure properties of an object or elements of an array into individual variables.

const person = {
  firstName: 'John',
  lastName: 'Doe',
  currentAge: 28
};

const {
  firstName,
  lastName,
  middleName,
  address = '',
  age: currentAge = 18
} = person;

console.log(middleName); // undefined
console.log(address); // ''
console.log(age); // 28
const display = (person) => {
  console.log(`${person.firstName} ${person.lastName}`);
}

const person = {
	firstName: 'John',
	lastName: 'Doe'
};
const display = ({firstName, lastName}) => { 
  console.log(`${firstName} ${lastName}`);
}

Object destructuring.
This technique is often used in React.

Destructuring

const score = [70, 80, 90, 100];


let [x, y, z] = scores;

console.log(x); // 70
console.log(y); // 80
console.log(z); // 90

Array Destructuring

const [a = 1, b = 2] = [10];
console.log(a); // 10
console.log(b); // 2
const getItems = () => null;

let [x = 1, y = 2] = getItems(); // Uncaught TypeError
let [a = 10, b = 20] = getItems() || [];

console.log(a); // 10
console.log(b); // 20

Arrow Functions

function add(x,y) {
  return x + y;
}
const add = (x, y) => x + y;
const add = (x, y) => { return x + y; };
const numbers = [4,2,6];
numbers.sort(function(a,b){ 
    return b - a; 
});
const numbers = [4,2,6];
numbers.sort((a,b) => b - a);
console.log(numbers); // [6,4,2]

Arrow functions provide you with an alternative way to write a shorter syntax compared to the function expression

Arrow Functions

const names = ['John', 'Mac', 'Peter'];
const lengths = names.map(name => name.length);

console.log(lengths); // [4, 3, 5]
const names = ['John', 'Mac', 'Peter'];
const onlyHasLongNames = names.every(name => name.length > 3);

console.log(onlyHasLongNames); // false
const names = ['John', 'Mac', 'Peter'];
const lengths = names.filter(name => name.length > 3);

console.log(lengths); //['John', 'Peter'];
const names = ['John', 'Mac', 'Peter'];
const hasOneLongName = names.some(name => name.length > 4);

console.log(hasLongName); // true

Classes

The class declaration is just syntactic sugar of the constructor function.

class Animal {
    constructor(type) {
        this.type = type;
    }
    identify() {
        console.log(this.type);
    }
}

let cat = new Animal('Cat');
cat.identify();
console.log(typeof Animal); // function
class Elephant extends Animal {
  constructor(anotherProp) {
   super('elephant');
   ...
  }
  walk() {
    super.identify();
    ....
  }
}

ES2020

Nullish Coalescing Operator

ES2020 introduced the nullish coalescing operator denoted by the double question marks (??).

The nullish coalescing operator is a logical operator that accepts two operands.

 

 

 

 

const result = (null || undefined) ?? 'OK'; 
console.log(result); // 'OK'
let person = {
  profile: {
    name: "",
    age: 0
  }
};

console.log(person.profile.name || "Anonymous"); // Anonymous
console.log(person.profile.age || 18); // 18
console.log(person.profile.name ?? "Anonymous"); // ""
console.log(person.profile.age ?? 18); // 0

Optional Chaining Operator

The optional chaining operator (?.) allows you to access the value of a property located deep within a chain of objects without explicitly checking if each reference in the chain is null or undefined.

const user = getUser(2);
const profile = user && user.profile;
const user = getUser(2);
const profile = user?.profile;

const avatar = user?.profile?.avatar;
let data = file.read();

let compressedData = file.compress();
// Error: Uncaught TypeError: file.compress is not a function
let compressedData = file.compress?.();
// undefined

Questions...

Additional resources:

modern-js

By Ruben Mateus

modern-js

A small presentation for modern day JS.

  • 143