Part 1



Course Link

What is ES?

ECMAScript is a standardized version of JavaScript with the goal of unifying the language’s specifications and features. As all major browsers and JavaScript-runtimes follow this specification, the term ECMAScript is interchangeable with the term JavaScript.

The most recent standardized version is called ECMAScript 6 (ES6), released in 2015. This new version of the language adds some powerful features including:

  • Arrow functions
  • Classes
  • Modules
  • Promises
  • Generators
  • let and const

1. Explore Differences Between the var and let Keywords

  • Why was let added as a keyword?
    • A variable with the same name can only be declared once using let
// var
var camper = 'James';
var camper = 'David';
console.log(camper);
// logs 'David'

//let
let camper = 'James';
let camper = 'David'; // throws an error
  • Compare Scopes of the var and let Keywords

    • When you declare a variable with the var keyword, it is declared globally, or locally if declared inside a function.

    • The let keyword behaves similarly, but with some extra features. When you declare a variable with the let keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.

var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3

is similar to

var numArray = [];
var i;
for (i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3

however, this can cause issues

var printNumTwo;
for (var i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// returns 3

let can fix it!

'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// returns 2
console.log(i);
// returns "i is not defined"

2. What is use strict?

The “use strict” enables Strict Mode, which catches common coding mistakes and “unsafe” actions.

  • Example 1
"use strict";
x = 3.14; // throws an error because x is not declared
  • Example 2
let catName;
let quote;
function catTalk() {
  "use strict";

  catName = "Oliver";
  quote = catName + " says Meow!";

}
catTalk();

3. Declare a Read-Only Variable with the const Keyword

  • const has all the awesome features that let has, with the added bonus that variables declared using const are read-only.
  • They are a constant value, which means that once a variable is assigned with const, it cannot be reassigned
  • You should always name variables you don’t want to reassign using the const keyword
function printManyTimes(str) {
  "use strict";
  // Only change code below this line
  const END_WORDS = " is cool!";
  const SENTENCE = str + END_WORDS;
  for (let i = 0; i < str.length; i+=2) {
    console.log(SENTENCE);
  }
  // Only change code above this line
}
printManyTimes("freeCodeCamp");

4. Mutate an Array Declared with const

  • Objects (including arrays and functions) assigned to a variable using const are still mutable. Using the const declaration only prevents reassignment of the variable identifier.
"use strict";
const s = [5, 6, 7];
s = [1, 2, 3]; // throws error, trying to assign a const
s[2] = 45; // works just as it would with an array declared with var or let
console.log(s); // returns [5, 6, 45]

5. Prevent Object Mutation

  • To ensure your data doesn’t change, JavaScript provides a function Object.freeze to prevent data mutation ❄️
  • Once the object is frozen, you can no longer add, update, or delete properties from it. Any attempt at changing the object will be rejected without an error.
function freezeObj() {
  'use strict';
  const MATH_CONSTANTS = {
    PI: 3.14
  };
  // Only change code below this line
  Object.freeze(MATH_CONSTANTS);


  // Only change code above this line
  try {
    MATH_CONSTANTS.PI = 99;
  } catch(ex) {
    console.log(ex);
  }
  return MATH_CONSTANTS.PI;
}
const PI = freezeObj();

5. Use Arrow Functions to Write Concise Anonymous Functions ➡️

  • In JavaScript, we often don’t need to name our functions, especially when passing a function as an argument to another function.

  • Instead, we create inline functions. We don’t need to name these functions because we do not reuse them anywhere else.

  • Example 1

const myFunc = function() {
  const myVar = "value";
  return myVar;
}
//  ES6 provides us with the syntactic sugar to not have to write anonymous functions this way. Instead, you can use arrow function syntax:
const myFunc = () => "value";
  • Example 2
const magic = () => {
  "use strict";
  return new Date();
};

6. Write Arrow Functions with Parameters ➡️

  • Just like a regular function, you can pass arguments into an arrow function
  • If an arrow function has a single argument, the parentheses enclosing the argument may be omitted
// doubles input value and returns it
const doubler = (item) => item * 2;
// or 
// the same function, without the argument parentheses
const doubler = item => item * 2;
  • It is possible to pass more than one argument into an arrow function
// multiplies the first input value by the second and returns it
const multiplier = (item, multi) => item * multi;
  • Example: write the myConcat function which appends contents of arr2 to arr1 so that the function uses arrow function syntax
const myConcat = (arr1, arr2) => {
  "use strict";
  arr1.concat(arr2)
}

console.log(myConcat([1, 2], [3, 4, 5]));

7. Set Default Parameters for Your Functions

  • In order to help us create more flexible functions, ES6 introduces default parameters for functions
const greeting = (name = "Anonymous") => "Hello " + name;

console.log(greeting("John")); // Hello John
console.log(greeting()); // Hello Anonymous
// Create an increment function by adding default parameters so that it will add 1 to number if value is not specified
const increment = (number, value=1) => number + value;

8. Use the Rest Parameter ...args with Function Parameters

  • In order to help us create more flexible functions, ES6 introduces the rest parameter for function parameters.
  • With the rest parameter, you can create functions that take a variable number of arguments.
  • These arguments are stored in an array that can be accessed later from inside the function.
  • The rest parameter eliminates the need to check the args array and allows us to apply map(), filter() and reduce() on the parameters array
  • Example
const sum = (x, y, z) => {
 const args = [x, y, z];
 return args.reduce((a, b) => a + b, 0);
}

// can be rewritten as 
const sum(...args){
 return args.reduce((a,b) => a+b,0)
}

9. Use the Spread Operator to Evaluate Arrays In-Place

  • The spread operator allows us to expand arrays and other expressions in places where multiple parameters or elements are expected
// ES5: We had to use Math.max.apply(null, arr) because Math.max(arr) returns NaN. Math.max() expects comma-separated arguments, but not an array. 
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); // returns 89

// ES6: ...arr returns an unpacked array. In other words, it spreads the array.
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr); // returns 89
  • The spread operator only works in-place, like in an argument to a function or in an array literal. The following code will not work:
const spreaded = ...arr; // will throw a syntax error
  • Example
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2;

arr2 = [];  // Change this line

console.log(arr2);

// rewritten as 
(function() {
  "use strict";
  arr2 = [...arr1]; // change this line
})();

10. Use Destructuring Assignment to Extract Values from Objects

  • Destructuring assignment is special syntax introduced in ES6, for neatly assigning values taken directly from an object
  • You can extract as many or few values from the object as you want
  • Example 1
//ES5
const user = { name: 'John Doe', age: 34 };

const name = user.name; // name = 'John Doe'
const age = user.age; // age = 34

//ES6
const { name, age } = user;
// name = 'John Doe', age = 34
// Here, the name and age variables will be created and assigned the values of their respective values from the user object. You can see how much cleaner this is.
  • Example 2
const HIGH_TEMPERATURES = {
  yesterday: 75,
  today: 77,
  tomorrow: 80
};

// Only change code below this line
const {today, tomorrow} = HIGH_TEMPERATURES; 

// Only change code above this line

11. Use Destructuring Assignment to Assign Variables from Objects

  • Destructuring allows you to assign a new variable name when extracting values. You can do this by putting the new name after a colon when assigning the value.
  • Example 1
const user = { name: 'John Doe', age: 34 };

//ES6
const { name: userName, age: userAge } = user;
// userName = 'John Doe', userAge = 34

12. Use Destructuring Assignment to Assign Variables from Nested Objects

const user = {
  johnDoe: { 
    age: 34,
    email: 'johnDoe@freeCodeCamp.com'
  }
};
// ES6 
// extract the values of object properties and assign them to variables with the same name
const { johnDoe: { age, email }} = user;
// assign an object properties' values to variables with different names
const { johnDoe: { age: userAge, email: userEmail }} = user;
  • Example 2
const LOCAL_FORECAST = {
  yesterday: { low: 61, high: 75 },
  today: { low: 64, high: 77 },
  tomorrow: { low: 68, high: 80 }
};

const {today:{low:lowToday, high:highToday}} = LOCAL_FORECAST

13. Use Destructuring Assignment to Assign Variables from Arrays

  • One key difference between the spread operator and array destructuring is that:
    • the spread operator unpacks all contents of an array into a comma-separated list. Consequently, you cannot pick or choose which elements you want to assign to variables.
// Destructuring an array lets us do exactly that:
const [a, b] = [1, 2, 3, 4, 5, 6];
console.log(a, b); // 1, 2

//  We can also access the value at any index in an array with destructuring by using commas to reach the desired index
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c); // 1, 2, 5
  • Exmple 2
let a = 8, b = 6;
// Use destructuring assignment to swap the values of a and b so that a receives the value stored in b, and b receives the value stored in a.
// Only change code below this line
[a,b ]=[b,a];
// Do not try to re-declare a or b while destructuring as they are already declared in the first let statement.

14. Use Destructuring Assignment with the Rest Parameter to Reassign Array Elements

  • In some situations involving array destructuring, we might want to collect the rest of the elements into a separate array
  • The result is similar to Array.prototype.slice(), as shown below
  • The rest element only works correctly as the last variable in the list. As in, you cannot use the rest parameter to catch a subarray that leaves out the last element of the original array.
  • Example 1
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
console.log(a, b); // 1, 2
console.log(arr); // [3, 4, 5, 7]
  • Example 2
const source = [1,2,3,4,5,6,7,8,9,10];
function removeFirstTwo(list) {
  "use strict";
  // Only change code below this line
  const [a, b,...arr] = list;
  // Only change code above this line
  return arr;
}
const arr = removeFirstTwo(source);

15. Use Destructuring Assignment to Pass an Object as a Function’s Parameters

  • In some cases, you can destructure the object in a function argument itself
  • This removes some extra lines and makes our code look neat
  • This has the added benefit of not having to manipulate an entire object in a function — only the fields that are needed are copied inside the function
  • Example 1
const profileUpdate = (profileData) => {
  const { name, age, nationality, location } = profileData;
  // do something with these variables
}
//ES6
const profileUpdate = ({ name, age, nationality, location }) => {
  /* do something with these fields */
}
// 
  • Example 2
const stats = {
  max: 56.78,
  standard_deviation: 4.34,
  median: 34.54,
  mode: 23.87,
  min: -0.75,
  average: 35.85
};

// Only change code below this line
const half = (stats) => (stats.max + stats.min) / 2.0; 
// Only change code above this line

//ES6
const stats = {
  max: 56.78,
  standard_deviation: 4.34,
  median: 34.54,
  mode: 23.87,
  min: -0.75,
  average: 35.85
};

// Only change code below this line
const half = ({ max, min }) => (max + min) / 2.0;
// Only change code above this line