ES6 new features

let and const

let and const

Read more for let/const in the Beginners Course Slides

The arrow function syntax

The arrow function syntax

arrow functions

ES6 introduces a new function declaration syntax called arrow notation
Synonyms:
Arrow functions
Fat arrow functions
Arrow functions are perfectly suited for Callback functions and Functional Programming constructs, like map, filter, reduce...
Check Functional-Light-JS Book by Kyle Simpson

Function expression vs arrow syntax - demo


				const pi = 3.14;

				// function declaration with expression:
				let circleAreaExp = function(r){
							return r*r*pi;
				}

				// function declaration with arrow syntax:
				let circleAreaArr = r=>r*r*pi;

				console.log( circleAreaArr(10) );
				console.log( circleAreaExp(10) );
			

syntax - full


				(param1, param2, …, paramN) => { statements }
			

				let circleArea = (r)=>{return r*r*pi};

				console.log(`circleArea(2) = ${circleArea(2)}`);
			

syntax - single parameter

If the function has only one parameter, you can omit the parentheses

				singleParam => { statements }
			

				let circleArea = r=>{return r*r*pi};

				console.log(`circleArea(2) = ${circleArea(2)}`);
			

syntax - single expression in body

If the function body is a single expression, you can omit curly braces and the return statement

				(param1, param2, …, paramN) => expression
			

				let circleArea = r=>r*r*pi;

				console.log(`circleArea(2) = ${circleArea(2)}`);
			

arrow syntax vs function definition - example


				let calculator1 = {
					'add': (a,b) => a+b,
					'sub': (a,b) => a-b,
					'mult': (a,b) => a*b,
					'div': (a,b) => a/b,
				}


				let calculator2 = {
					'add': function(a,b){return  a+b},
					'sub': function(a,b){return  a-b},
					'mult': function(a,b){return  a*b},
					'div': function(a,b){return  a/b},
				}


				console.log( calculator1.add(2,3) );
				console.log( calculator2.add(2,3) );

			

lexical arguments

the arguments object in arrow function is reference to the arguments object in the enclosing scope
Remember, that this is not the case with function definition/expression

				const dirFuncExprArgs = function() {
					console.dir(arguments);
				}

				let dirArrowArgs = ()=>{
					console.dir(arguments);
				}

				dirFuncExprArgs(1,2,3); // [1,2,3]
				dirArrowArgs(1,2,3);    // error in browsers
			

lexical arguments - example


				function foo() {
					console.log(`arguments in foo:`);
					console.dir(arguments);

					const bar = () => {
						console.log(`arguments in bar:`);
						console.dir(arguments);
					}
					bar(4,5,6);
				}

				foo(1,2,3);

				// arguments in foo:
				// [Arguments] { '0': 1, '1': 2, '2': 3 }
				// arguments in bar:
				// [Arguments] { '0': 1, '1': 2, '2': 3 }
			

lexical "this"

"this" value in arrow functions is lexically scoped in contrast to standard functions, whose "this" value is dynamically scoped.
I.e the value of "this" in arrow functions is this same as the value of "this" in the enclosing scope.
"this" in arrow functions can not be changed with call/apply or bind methods!

the "this" value, as well as the call/apply/bind methods are discussed in further topics.

lexical "this" - example


				lexicalThis = this;

				var obj = {
					'exp': function(){
						console.log(this === lexicalThis);
					},
					'arr': ()=>{console.log(this === lexicalThis)}
				}

				obj.exp(); // false
				obj.arr(); // true
			

lexical "this" - example


				let user = {
					'userName': 'Ada Byron',
					'greet': function () {
						console.log(`Hello, I'm ${this.userName}`);
					},
					'greetArr':  () =>  console.log(`Hello, I'm ${this.userName}`)
				}

				user.greet();
				user.greetArr();

				// Hello, I'm Ada Byron
				// Hello, I'm undefined
			

loose binding


				let cb;

				cb = cb || function() {}; // ok

				cb = cb || () => {};
				// SyntaxError: invalid arrow-function arguments

				cb = cb || (() => {});		// ok
			

Notes

Arrow functions are always anonymous!
They are perfect for callbacks
Arrow functions cannot be used as constructors and will throw an error when used with new
Because of their lexical binding, no need to add this.handleClick = this.handleClick.bind(this) in the constructor.

Default parameter values

Default parameter values

Before ES6


			function f(x, y, z){
				x = x || 1;
				y = y || 2;
				z = z || 3;

				console.log(x, y, z); //6,7,3
			}
			f(6, 7);
		

After ES6


			function f(x=1, y=2, z=3){
				console.log(x, y, z); //6,7,3
			}
			f(6, 7);
		

The spread operator

The spread operator


			myFunction(...iterableObj);
		

			[...iterableObj, 4, 5, 6];
		
Converts an iterable object (for now, you can simply think of it as an JS array or the DOM ) into a list of values
Iterable objects are those which prototype implements an @@iterator method (more on MDN...)

spread operator in function call - example


			function foo(a,b,c){
				console.log(`a=${a}`)
				console.log(`b=${b}`)
				console.log(`c=${c}`)
			}

			var args = [1,2,3];
			foo(...args);

			//a=1
			//b=2
			//c=3
		

spread operator in array literal - example


			let arr1 = [1,2,3];
			let arr2 = [4,5];

			let arrNew = [ ...arr1, ...arr2];

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

The rest parameter

The rest parameter

The last parameter of a function prefixed with " ... " is called as a rest parameter
replaces the arguments object
In contrast with arguments object, the ...rest parameter is an array type

example


			function f(a, b, ...args){
				console.log(args); //"3, 4, 5"
			}

			f(1, 2, 3, 4, 5);
		

De-structuring assignments

De-structuring assignments

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
Reference: Destructuring_assignment @mdn

Array destructuring - examples


      // assign variables from array:
      let [a, b] = [1,2];
      console.log(`a = ${a}; b = ${b}`); // a = 1; b = 2

      // same as above - no matter that we pass more elements:
      let [a, b] = [1,2,3,4,5];
      console.log(`a = ${a}; b = ${b}`); // a = 1; b = 2

      // assign variables from array in conjunction with rest syntax:
      let [a, ...rest] = [1,2,3];
      console.log(a);     // 1
      console.log(rest);  // [2, 3]
    

use case: swapping variables values


      let a = 1, b = 2;

      // we do the swap without tmp variable, just with one line:
      [a,b] = [b,a];

      console.log(`a = ${a}; b = ${b}`); // a = 2; b = 1
    

Object destructuring

Destructuring on objects let us bind variables to different properties of an object.
There is a nice syntactical shortcut for when the property and variable names are the same

      let obj = {p1: 1, p2: 2};

      // assign obj properties to variables with same name:
      let {p1, p2} = obj;

      console.log(p1);  // 1
      console.log(p2);  // 2
    

New object literal features

New object literal features

Shorthand property names

Declaring an object literal with keys that match variables is quite common use case. In such situations property values shorthands is quite useful:

      let userName = 'pesho';
      let userAge = 23;

      // ES6 way:
      let p1 = {userName, userAge};

      // ES5 way:
      // let p1 = {userName:userName, userAge:userAge};

      console.log(p1); // { userName: 'pesho', userAge: 23 }
    

Method definitions

ES6 introduces a shorter syntax for method definitions on objects initializers:

      let p1 = {
        name: 'Pesho',
        greet(){
          console.log(`Hi, I'm ${this.name}`);
        }
      }

      p1.greet(); // Hi, I'm Pesho
    

These slides are based on

customised version of

Hakimel's reveal.js

framework