ECMA - GradedJestRisk/js-training GitHub Wiki

Table of Contents

General

Overview:

  • JavaScript
  • high-level, interpreted, curly-bracket syntax, dynamic typing
  • support event-driven, functional, and imperative (eg. object-oriented)
  • does not include any I/O (networking, storage, graphics facExportsilities) => relies upon the host environment
  • scope
    • initial: client-side in web browsers (vanilla JS)
    • later:
      • executes JS code outside of a browser (Node.js)
      • library for building user interfaces (React.js)
      • frameworks (Vue.js, Angular.js, Express.js)
A few links:

Timeline

Version:

  • (Head first JS: 2014 - does NOT include ECMA6)
  • 6: ES2015 (Harmony) - feature list
    • add let to restrict variable scope to a code block (var declare a function-based scope)
    • add class declarations class Foo { ... }
    • add modules
//  lib/math.js
export function sum (x, y) { return x + y }
export var pi = 3.141593

//  someApp.js
import * as math from "lib/math"
console.log("2π = " + math.sum(math.pi, math.pi))

import * as moduleName from "..."; export const Foo;

    • add iterators and for/of
    • add constant variable declaration const
    • add new collection type: maps, sets
    • destructuring assignment var list = [ 1, 2, 3 ]; var [ a, , b ] = list; [ b, a ] = [ a, b ];
    • array find
[ 1, 3, 4, 2 ].find(x => x > 3) // 4
[ 1, 3, 4, 2 ].findIndex(x => x > 3) // 2

Basic blocks

List:

  • primitive types: number, boolean, strings, array
  • special types: function, object, String, Array
  • variables: local and global

Symbols

element chars symbol sample
end of statement ; semi colon return;
assignment (value/ref) = equal
var name   = "joe";
var person = { name:"joe", age:19 };
object definition (property value - function definition assigner) : colon
var person = { 
   name  : "joe",
   assign: function(role){(..)}
};
function parameters () parentheses function assign (person, role)
array constructor [] square brackets myArray = ["apple", "orange"]
code block
object definition
{} curly braces
else {console.log("")}
var person = { name:joe, age:19 }
delimiter , comma
function assign (person, role)
var person = { name:joe, age:19 }
anonymous functions => fat arrow/comma, hash rocket (x => x*x)(10) [evaluate to 100]

Variables

Variable declaration

invaluable article here

best practice ?

You can declare your variable "name" (aka identifier, not type).
Its value will be undefined (known as hoisting).
But JavaScript does not require that.

enforce

It will prevent you to implicitly create global, hidden in closures.

"use strict";
x = 3.14;  
Uncaught ReferenceError: x is not defined

See modes

scoping / mutability

Overview

keyword stands for scope mutability sample
empty global global mutable i = 8 ;
var variable function mutable var i;
let constant block mutable let i;
const constant block immutable const i;

How to

Introduce a variable:

  • start with const in const myWellNamedVariable; in the innermost code block;
  • if you need mutability, switch to let;
  • if you need function scoped:
    • move let declararation to function uppermost code block
    • if you're still dissatisfied (why ?), think twice, and then with pain, replace let by var.
To sum up, except when you need a closure, always declare your variable.

Object

Creation, 2 ways:

  • object literal:
    • straightforward: const person = { name: 'joe', age:19 };
    • step-by-step:
const person = {};
person.name =  'joe';
person.age = 19;
  • object constructor
     var person = new Person{ joe, 19 } ;
Copy objects, see here

Function

Overview

JavaScript has:

  • first-class functions
    • function as argument and variable
    • function that create function, aka lambda
  • naming:
    • named
    • anonymous
  • invocation mode:
    • invoked later
    • immediately invoked (Immediately Invoked Function Expression, IIFE)
Function should be seen as a broad concept, the following syntax-correct function:
  • take no argument;
  • does not return anything;
  • has no side-effect;
  • store no code
  • store some state.
const myStrangeFunction = function(){
   state : 'hidden_state';
};
const result = myStrangeFunction();

A function is a regular JS object, but can be seen as, in addition, to:

  • has a string containing code
  • can be invoked
  • receive arguments and returns values.
const body = "return Math.PI * radius * radius";
var circle = new Function("radius", body);
console.log(circle(1));

General

Function:

  • reuse code
  • named block with arguments
  • invoke with ()
  • pass variables as argument
  • return variables

Syntax

Declare function:

  • standalone: function <FUNCTION_NAME> (<PARAMETERS>){(..)} ,
    eg function assign (person, role){..}
  • object: <FUNCTION_NAME>: function(<PARAMETERS>){(..)} ,
    eg assign: function (person, role){..}

Overview

You will met these forms.
Functions are not invoked here.

code name type invoke scope
function greet(name) {}; definition definition N times global ?
greetFunction = function greet (name) {}; expression named N times global ?
greetFunction = function (name) {}; expression anonymous (standard) N times global ?
greetFunction = (name) => {}; expression anonymous (arrow) N times global ?

You can assign a function expression to :

  • a variable with =
  • an object property with :

IIFE

They are invoked when defined.
As such, their syntax is ( definition ) (argumentValue)
They can be:

  • named
  • anonymous (arrow or regular)

More on this

Arrow functions

General

Arrow function show input => ouput .
The usual form being

function increment(input) { 
   const out put = input + 1;
   return ouput 
}

Its aims to add expresiveness for short function bodies.

More symbols are required to handle:

  • additional parameters;
  • statement instead of expressions.

So forget using arrow functions if it ends up making your code more complex that not.
const myFn = (x) => {
  return x + 1;
};

const myFn = (x) => x + 1;

const myFn = x => (x + 1);

const myFn = x => x + 1;

The better choice is the latter: x => x + 1

They have their own scope rules, especially on this keywords to prevent side effects.

as IFEII

Functions are always invoked here ()

parameter body syntax sample
(none) expression () => expression () () => 'foo' ()
1 expression parameter => expression ( name => name.length ) ()
>1 expression (firstParameter, secondParameter) => expression
>1 statement (firstParameter, secondParameter) => { (statements) }

currying

aimed at reuse/expressiveness

sample

A function that sums two number:

  • standard way
const add = (a, b) => a + b
add(1, 2)
  • currified way
const add = a => b => a + b
add(1)(2) 

Step by step:

  • takes one argument
  • return another (anonymous) function that
    • takes the second argument
    • add both elements
    • return the result.

The second form works because x is still in scope (thanks to closure).

another example: reuse

Let's figure two objects having a common property, id, stored in a collection
To extract all ids, we need to write down twice the map code.

movies.map( (movie) => movie.id ) 
series.map( (serie) => serie.id ) 

With currying:

  • let's create an generic accessor const get = property => object => object[property];
  • and then a specific accessor for id property const getId = get('id');
  • now, we can use it on any object
movies.map(getId); 
series.map(getId); 

Typing

Overview

JavaScript is a:

  • dynamic typing: useless to declare a variable type;
  • weak type check: you can combine different type in expressions.

Conversion rules

See reason here

Equality

== or ==, this is the question ?

Collections

Overview:

  • Array
  • Map
  • Set
  • String
let string = 'this is a string';

for (let char of string) {
  console.log("Character :", char);
}

let string = 'this is a string';
for (let char in string) {
  console.log("Character :", char);
}

Arrays

Overview

List: declare: let myArray = [];

methods

method/property Use sample
length array size let arraySize = anArray.length;
concat return an array with both array elements let totalArray = beginningArray.concat(endArray);

Destructuring

| code samples

Module

JS module enable:

  • modularity: subdivides a system into smaller parts, which can be independently created, modified or exchanged between different systems.
  • restrict public interface (hide implementation details).
Module can contain functions and values, not only classes. However, it's a good idea to put class in a module, usually one each, although you don't have to.

2009 : Node module (aka CommonJS module)

See node

2017 : ECMA module

All module's mode is strict, see modes

export

file is prototype.js

const makeAgedBrie = function (agedBrieParams) {(..)};

// export
export Item;
export Shop;
export makeAgedBrie,

OR
export { Item, SHop, makeAgedBrie}

More in API

import

file is prototype.test.js

// import
import {Shop, Item, makeAgedBrie} from "./prototype";
OR
import from "./prototype";

// use
const standardItem = new Item(standardItemParams) ;

You can rename module and imports, see API

You can:

  • rename (to avoid name clash) import { export1 as alias1 } from "module-name";
  • omit a name import defaultExport from "module-name";
  • execute code and discard the reference (side-effect only): import '/modules/my-module.js';

prototype

ES5 (2009): prototype keyword

Prototype-based API

File is rectangle.js

function Rectangle(width, height) {
  this.height = width;
  this.width = height;
}

Rectangle.prototype.area = function() {
    return this.height * this.width;
};

File is rectangle.test.js

const Rectangle = require('./rectangle');
const rectangle = new Rectangle(2, 4);
console.log(rectangle.area()); // 8

ES6 (2015): class keyword

class

Syntax

File is rectangle.js

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  area() {
    return this.height * this.width;
  }
}

File is rectangle.test.js

const Rectangle = require('./rectangle');
const rectangle = new Rectangle(2, 4);
console.log(rectangle.area()); // 8

See also:

  • binding a function to the object to compute a value without executing it: get keyword
  • class-level
    • methods: inside class definition, using static keyword
    • properties: outside of class definition, Rectangle.hasFourSide = true
  • invoking parent with super keyword
  • mix-in: can be implemented a function, taking a superclass as input, outputting the subclass
Mixin : a class that contains methods for use by other classes without having to be the parent class of those other classes.

inheritance

File animal.js

class Animal { 
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

File dog.js

class Dog extends Animal {
  constructor(name) {
    super(name); // call the super class constructor and pass in the name parameter
  }

  speak() {
    console.log(`${this.name} barks.`);
  }
}

File animal.test.js

let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.

Introducting scope (still not fully supported by FF)

public

class Rectangle {
  height = 0;
  width;
  constructor(height, width) {    
    this.height = height;
    this.width = width;
  }
}

private

class Rectangle {
  #height = 0;
  #width;
  constructor(height, width) {    
    this.#height = height;
    this.#width = width;
  }
}

promise

States:

  • pending: initial state, neither fulfilled nor rejected.
  • fulfilled: meaning that the operation completed successfully.
  • rejected: meaning that the operation failed.
Friend:
  • await: to wait for a Promise. It can only be used inside an async function.

console

A list:

  • list all object properties: console.dir
  • list all collection members: console.table
  • format:
    • indent: console.group()
    • unindent: console.groupEnd()
  • timer:
    • start: console.time()
    • stop: console.timeEnd()

modes

Two modes:

  • strict;
  • sloppy.
Strict can be activated for a file, or only inside a function
"use strict"; 
myFunction {
   "use strict"; 
}

Be aware that strict mode change other behaviours ! eg. this keyword: full list here

Can strict considered harmful ?

Replace lodash by ECMA

some examples

⚠️ **GitHub.com Fallback** ⚠️