JavaScript

Slack

JavaScript Syntax

First: The basics

Variable declaration

// ES5
var foo;
var bar;

// ES6
let foo;
const bar = 'bar';

Variable declaration

// ES5
var foo = 5;
var bar = true;
var zet = 'zet';
var list = [];
var obj = {};

Variable declaration

var foo = [1, 2, 3];
var foo = {
  property: false,
  otherProperty: 15
}

Variable declaration

var foo = [{
  name: 'test',
  email: 'test@email.com'
}, {
  name: 'test2',
  email: 'test@email.com'
}]

Variable declaration

var foo = {
  name: 'test',
  email: 'test@email.com',
  list: [1, 3, 4, 5],
  otherProperty: {
    hello: stuff
  }
}

Variable assignation

var salvame;
salvame = null;

var telecinco = null;
telecinco = 0;

Variable assignation

var salvame;

function doNotWatchTv() {
   salvame = null;
}

doNotWatchTv();

Variable assignation

var salvame;
telecinco = 0;

function doNotWatchTv() {
   salvame = null;
}

var telecinco;

doNotWatchTv();

Where do i declare my variables?

Hoisting

It's always better to declare your variables at the top because JavaScript moves variable declarations at the top in a process called hoisting

Operators

 

Operators

 

Unary operators

 

A unary operator is one that takes a single operand/argument and performs an operation.

OperatorExplanation

Unary plus (+) Tries to convert the operand into a number
Unary negation (-) Tries to convert the operand into a number and negates after
Logical Not (!) Converts to boolean value then negates it
Increment (++) Adds one to its operand
Decrement (--) Decrements by one from its operand
Bitwise not (~) Inverts all the bits in the operand and returns a number
typeof Returns a string which is the type of the operand
delete Deletes specific index of an array or specific property of an object
void Discards a return value of an expression.

+ operator

Tries to convert the operand to a number

+3                                   // returns 3
+'-3'                                // returns -3
+'3.14'                              // returns 3.14
+'3'                                 // returns 3
+'0xFF'                              // returns 255
+true                                // returns 1
+'123e-5'                            // returns 0.00123
+false                               // returns 0
+null                                // returns 0
+'Infinity'                          // returns Infinity
+'infinity'                          // returns NaN
+function(val){  return val }        // returns NaN

+ operator

If a object has a valueOf method, that value will be returned

+{
  valueOf: function(){
    return '0xFF'
  }
}

//255

- operator

Tries to convert the operand to a number, but performs a negation

    -3                               // returns -3
    -'-3'                            // returns 3
    -'3.14'                          // returns -3.14
    -'3'                             // returns -3
    -'0xFF'                          // returns -255
    -true                            // returns -1
    -'123e-5'                        // returns -0.00123
    -false                           // returns -0
    -null                            // returns -0
    -'Infinity'                      // returns -Infinity
    -'infinity'                      // returns NaN
    -function(val){  return val }    // returns NaN
  -{                                 
    valueOf: function(){
      return '0xFF'
    }
  }                                //returns -255

! operator

Converts the value to it's boolean representantion before negating 

!false        // returns true
!NaN          // returns true
!0            // returns true
!null         // returns true
!undefined    // returns true
!""           // returns true
!true         // returns false
!-3           // returns false
!"-3"         // returns false
!42           // returns false
!"42"         // returns false
!"foo"        // returns false
!"true"       // returns false
!"false"      // returns false
!{}           // returns false
![]           // returns false
!function(){} // returns false

!! operator

Converts the value to it's boolean representation

!!false        // returns false
!!true         // returns true
!!1            // returns true
!!0            // returns false

++ operator

Increments by one it's value

Can be used in 2 ways.
Before:

var x = 5;
var y = ++x;

// x === 6 
// y === 6
var x = 5;
var y = x++;

// x === 6
// y === 5

After
It returns the value before modifying

-- operator

Decrements by one it's value

Can be used in 2 ways.
Before:

var x = 5;
var y = --x;

// x === 4 
// y === 4

After
It returns the value before modifying

var x = 5;
var y = x--;

// x === 4
// y === 5

typeof operator

returns a string indicating the type of the value

typeof 2                                       // returns 'number'
typeof true                                    // returns 'boolean'
typeof null                                    // returns 'object'
typeof Infinity                                // returns 'number'
typeof '2'                                     // returns 'string'
typeof '-3'                                    // returns 'string'
typeof 'infinity'                              // returns 'string'
typeof Date()                                  // returns 'string'
typeof [1,2,3]                                 // returns 'object'
typeof {hi: 'world'}                           // returns 'object'
typeof function(val){  return val }            // returns 'function'
typeof undefined                               // returns 'undefined'
typeof hi                                      // returns 'undefined'
typeof NaN                                     // returns 'number'
typeof new Date()                              // returns 'object' 

delete operator

deletes a object propery and returns true if it was succesful

// Deleting a property with the dot notation
var pub = { bar: "42" };
delete pub.bar;              // returns true
console.log(pub);            // returns {}

// Deleting a property that does not exist
var lunch = { fries: 1 };
delete lunch.beans;          // returns true
console.log(lunch);          // returns { fries: 1 }

// Deleting a non-configurable property of a predefined object
delete Math.PI;              // returns false  
console.log(Math.PI);        // returns 3.141592653589793

delete operator

deletes a object propery and returns true if it was succesful

// Deleting a property with the dot notation
var pub = { bar: "42" };
delete pub.bar;              // returns true
console.log(pub);            // returns {}

// Deleting a property that does not exist
var lunch = { fries: 1 };
delete lunch.beans;          // returns true
console.log(lunch);          // returns { fries: 1 }

// Deleting a non-configurable property of a predefined object
delete Math.PI;              // returns false  
console.log(Math.PI);        // returns 3.141592653589793

non configurable properties

delete has no effect on non configurable properties

var Person = {};
Object.defineProperty(Person, 'name',
 {  
    value: 'Scot',
    configurable: false
})

// Defines an object property and sets it to non-configurable
console.log(Person.value);                 // returns 'Scot'
delete Person.value                        // returns false
console.log(Person.value);                 // returns 'Scot'

== Comparission / unestrict equality

1    ==  1        // true
"1"  ==  1        // true
1    == '1'       // true
0    == false     // true

0    == null      // false
0    == undefined // false
null == undefined // true

Tries to  convert it's type

== Comparission

[] == [] // false
{} == {} // false
// Not same reference of memory

Comparission Common pitfails

// Is true
console.log([10] ==  10)
// Is true
console.log('10' ==  10)
// Is true
console.log([]  ==  0)
// Is true
console.log(''  ==  false)

=== Comparission / strict equality

1 === 1  // true
1 === '1' // false
false === 0 // false

Enforces strict type equality

!= unestrict inequality / !== strict inequality

1 !=   2     // true
1 !=  '1'    // false
1 !=  "1"    // false
1 !=  true   // false
0 !=  false  // false

1 !==   2     // true
1 !==  '1'    // true
1 !==  "1"    // true
1 !==  true   // true
0 !==  false  // true

>, <, >=, <= relational operators

0 >= null // true
0 < null // false
1 < '3' // true 
'z' > 'a' // true

 JavaScript coerces into its primitive number type

Logical operators

Logical operators are used to determine the logic between variables or values.

&&

||

!

Logical operators

Logical operators are used to determine the logic between variables or values.

(x < 10 && y > 1) // true
1 && "false"  // true


1 || false // true
0 || "true" // true

truthy falsey

Truthy: Something which evaluates to TRUE.
Falsey: Something which evaluates to FALSE.

undefined, null, NaN, 0, "" (empty string), and false

logical operator assignation

&& gives you the last value
|| gives you first value

3 && 7 // 7
3 || 7 // 3

false || 7 // 7

Arithmetic Operators

// Sum tries to perform string or number additions
var a = 5
a = a + 5
// Same as
a += 5

// Multiply only has number coercion
var a = 5;
a = a * 10
// Same as
a *= 10


Arithmetic Operators

// Division operator
var a = 5
a = a / 5
// Same as
a /= 5

// Remaining operator
var a = 6;
a = a % 5
// Same as
a %= 5


Arithmetic Operators

// exponentation operator
var a = 5
a = a ** 3
// 125

Arithmetic Operators Common Pitfails

// Number + Number -> addition
console.log(1 + 2);

// Boolean + Number -> addition
console.log(true + 1)

// Boolean + Boolean -> addition
console.log(false + false);

// Number + String -> concatenation
console.log(5 + 'foo')

// String + Boolean -> concatenation
console.log('foo' + false)

// String + String -> concatenation
console.log('foo' + 'bar')

Arithmetic Operators Common Pitfails


// String - Number -> NaN
console.log('foo' - 3)

// The addition operator performs string or number operators.
// JavaScript will translate [] into it's string equivalent ''
console.log([] + []) 
// empty string
// [].toString() + [].toString()

// The operator - is not defined for strings
// then JavaScript will transform the value to number
console.log([] - []) 
// Number([]) - Number([])
// NaN

WAT

Ternary operator

var result = condition ? result1 : result2

var result = 0 == false ? 15 :  20

var otherResult = [] == [] ? 15 : 20

.... Spread operator
spread syntax

The spread operator allows an array to be expanded where N arguments for function calls or array elements are expected

.... Spread operator
spread syntax

var list = ['a', 'b', 'c']

function log(x, y, z) {
   console.log(x, y, z)
}

log(...list)

.... Spread operator
spread syntax

var list = ['a', 'b', 'c']

function log(x, ...rest) {
   console.log(x, rest)
}

log(...list)

.... Spread operator
spread syntax

var list = ['a', 'b', 'c']

var newList = ['d', 'e', ...list, 'z' ]

Spread operator exercise

- merge two arrays [1, 2, 3] [4, 5, 6]
 

- Define a function that receives several arguments, call that function with the array values spreaded

.... Spread operator
spread syntax

The spread operator allows an object to be expanded inplaces where N object key-value pairs are expected

.... Spread operator
spread syntax

var obj = {
   field: 'value',
   anotherField: 'value2'
}

var newObj = {
   ...obj,
   thirdField: 'value3'
}

Spread operator exercise

Merge two objects.

.... Spread operator
destructuring assignment

const allNumbers = [1, 2, 3, 4]

const [first, second, ...rest] = allNumbers

// first 1
// second 2
// rest [3, 4]

.... Spread operator
destructuring assignment

const user = {
    name : 'myname',
    address: {
        city: 'madrid'
    },
    pwd: '134'
}

const { name, ...restObjData } = user

Destructuring assignment exercise

Given an array [1,2,3,4,5,6], get the last 3 items in a new array copy.

Scope & Closures

 

Scope

scope determines the visibility of variables and other resources in areas of your code.

There are 3 types of scope: Global, local and block

Scope

A new function creates a new scope. That scope is local to that function.

var x = 0; // Global scope

function doMaths() {
   var y = 0;
}

console.log(x);
// console.log(y)?

Scope

the control structures create a new block scope

var x = 0; // Global scope

function doMaths() {
  for(let i = 0; i < 10; i++) {
    // Block scope
  }

  // console.log(i)?
}

console.log(x);
// console.log(y)?

Scope

for (var i = 0; i < cars.length; i++) {
  // i is visible here
}

// i is visible here


for (let x = 0; x < cars.length; x++) {
  // x is visible here
}

// x is not visible here

var is scoped to the nearest function block and let is only defined in the current block of code

Scope

We can access the parent scope

var x = 1; // Global scope

function doMaths() {

  var b = 3;

  function sum() {
    return x + b;
  }
  
  return sum();
}

Scope

We can access the parent scope

var x = 1; // Global scope

function doMaths() {

  var x = 3;
  
  x = 5 + x;

  return x
}

Closures

A Closure is created when an inner function tries to access the scope chain of its outer function

function makeSumator(a) {
  var x = 3;
  return function(b) {
    return b + x + a
  }
}

const sumatorThree = makeSumator(3)
const sumatorSeven = makeSumator(7)

sumatorThree(5) // 5 + 3 + 3
sumatorThree(6) // 6 + 3 + 3

sumatorSeven (5) // 5 + 3 + 7
sumatorSeven (6) // 6 + 3 + 7

Closures

makeSumator is a function factory that creates functions.

 

sumatorThree and sumatorSeven are both closures, they share the same body definition but have different lexical environment

Closures exercise

Create a function that:

- has a internal counter

- whenever i call the function the counter gets incremented. 

- No one else can modify the counter (is not in the global scope)

Functions

 

=> 

Functions

Functions are "subprograms" that can be executed

Functions

Functions have arguments and a body

function doSomething(arg1, arg2) {
  // Do something fancy with arg1 or arg2
}

Functions

function arguments are passed by value, but if they are an object they get passed by reference

Functions

var x = { 
  thing : true
}

var name = 'name'

function doSomething(arg1, arg2) {
   arg1.thing = false
   arg2 += ' surname'
}

doSomething(x, name)

Functions

function myThing() {
   return function() {

   }
}

Functions can have a name or be anonymous

Functions

(function() {
    // statements
})();

functions can be invoked only once
 

Functions

new Function (arg1, arg2, ... argN, functionBody)

functions can be created with the Function constructor

JavaScript supports different styles of programming

  1. Imperative
  2. Object Oriented 
  3. Functional

Modern tendencies are influenced by the functional approach

  1. Inmutable data
  2. Pure functions
  3. Redux / RxJS ...

JavaScript can be functional

High order functions. The ability to pass functions as arguments, assign them to variables, return functions...

function doSomething() {
    return function() {
        // HI!
    }
}

return functions

function doSomething(cb) {
    return function() {
        console.log('hey');
        cb();
    }
}

pass functions as arguments

function unless(test, then) {
  if (!test) then();
}

unless(x, function() {
    // Only if x is falsy
})

even create new structures of control

Anonymous functions and lambda syntax () => x

x => x * 2


const multiplyItemsBy2 = (a) => a.map(x => x * 2)

JavaScript can be functional

What is not a pure function?

var x = {
  prop: 'pepito'
}

function stuff(obj) {
  obj.casa = 'negra'

  return obj
}

/* Not good */
stuff(x)

JavaScript can be functional

What is a pure function?

var x = {
  prop: 'pepito'
}

function stuff(obj) {
  return Object.assign({}, obj, { casa: 'negra' })
}

/* Much better */
stuff(x)

To determine if a function is impure, if we call a function and expect no return value we can deduce that the function is not pure.
For functional programming returning no value means the function does nothing.

Inmutability. For ensuring functional programming and avoiding side effects.

For example, we can create new objects with:

Object.assign({}, myObj, newProperties);

{
  ...myObj,
  ...newProperties
}

JavaScript functional - Level 2

Create pure function that
- Receives a user object and a newData object

- Returns a new object with both of the data combined

 

TIP: Use spread operator or Object.assign

Values we want to achieve

Having small & concise pieces of code that have no side effect, that can be both testable and composable. Super fancy shit yeah.

...this is not a religion

You can combine OOP with functional programming 

Utilities

Function composition

 

Function composition is the process of combining two or more functions to produce a new function.

A maths example: f(g(x))
Reads as x then g then f

 

JavaScript can be functional

Function composition

function add(a, b) {
   return a + b
}

function multiply(a, b) {
   return a * b
}

const result = add(multiply(3, 2), 5)

Function composition exercise

Combine 3 functions in the way f(g(c(x))) that will modify a number in different ways using arithmetic operators.

JavaScript functional

Given a user that has 2 number properties (age and money) combine 2 functions in the way:

            f(g(x))


that return the a number equaling the age and money of the user multiplied between them, where x is the user.

JavaScript functional

function multiply(a, b) {
  return a * b
}

function takeAgeAndMoney(u) {
  return [u.age, u.money]
}

const u = {
  age: 10,
  money: 20
}

multiply(...(takeAgeAndMoney(u)))

JavaScript can be functional

Partial application

Giving a function with M arguments. Is the process of applying a function with N arguments and return a function with X arguments

Where: M > N

and : M > X

Partial application

function add(a) {
   return function(b) {
      return a + b
   }
}

const sumPartial = add(3)

JavaScript functional - Level 1

const suma = (a, b) => a + b

const sumaCurrificada = (a) => (b) => a + b
// Or partially applied

suma3 = sumaCurrificada(3)

suma3(2) // 5

Partial application

JavaScript functional - Partial Application

Create a function that:

- Do needs 4 parameters to be completed.

- Returns a function with half of its parameters

 

JavaScript can be functional

Currying

 

Is the process of receiving a function with multiple parameters and returning a function with exactly ONE parameter

JavaScript can be functional

Currying

function toloco(one, two, three, four) {
   // Do something
}

const toCurry = curry(toloco)

const toCurryA = toCurry(a)
const toCurryB = toCurry(b)

toCurryA(b)

JavaScript functional - Level 1

Create a function that receives 3 arguments and currify it.

Create different variations of the remaining function executions, each one will have it's own closure.

Inmutable array iteration

Without map...

const users = [{
  name: 'Pedro',
  age: 15
}, {
  name: 'Javier',
  age: 30
}, {
  name: 'Maria',
  age: 25
}]

const userAges = []

for(var i = 0; i < users.length; i++) {
  userAges.push(users[i].age)
}

// [15, 30, 25]

Map
Array has different methods, one of them is .map() which is really useful in functional programming. It returns a new array with the returned result of the callback function

const users = [{
  name: 'Pedro',
  age: 15
}, {
  name: 'Javier',
  age: 30
}, {
  name: 'Maria',
  age: 25
}]

const userAges = users.map(u => u.age)

// [15, 30, 25]

Map

Array methods are also chainable...

const takeAge = (u) => u.age
const squareIt = (n) => n * n

users.map(takeAge)
    .map(squareIt)

[].reduce
 

const ages = users.reduce(function(acc, next) {
  return acc + next.age
}, 0)

Putting this together...

const users = [{
  born: 1985,
  died: 2017,
  sex: 'm'
},{
  born: 1955,
  died: 2017,
  sex: 'm'
},{
  born: 1935,
  died: 2017,
  sex: 'm'
},{
  born: 1995,
  died: 2008,
  sex: 'f'
}{
  born: 1985,
  died: 2017,
  sex: 'f'
},{
  born: 1955,
  died: 2001,
  sex: 'f'
}]

JavaScript functional - Level 3 - Time 15 min

Create a script that combines the following techniques:

- Function composition

- Array map

- Array reduce

 

JavaScript functional - Level 4 - Time 15 min

Create a function that filters a subset of data.

 

Find one of the items by name.

Putting this together...

function average(array) {
  function plus(a, b) { return a + b; }
  return array.reduce(plus) / array.length;
}
function age(p) { return p.died - p.born; }
function male(p) { return p.sex == "m"; }
function female(p) { return p.sex == "f"; }

console.log(average(ancestry.filter(male).map(age)));
// → 61.67
console.log(average(ancestry.filter(female).map(age)));
// → 54.56

To the machine

Install nodejs

A quick intro to unit testing

Testing

What is Unit testing?

Unit testing is the process of writing tests for small units of code. This process ensures that the code works correctly and accomplishes it's purpose.

It should be isolated from the dependencies

Testing

BDD?

 BDD is a set of best practices for writing great tests. BDD can, and should be, used together with TDD and unit testing methods.

It enforces focusing on what the code should do rather than in the implementation details

Testing

What is mocha?

Mocha is a test framework that runs in NodeJs and in the browser.
 

Testing

It allows us to define the test suites as the following

describe('My test suite', () => {
  
  describe('one thing', () => {
    
    it('should go well', () => {
      assert.ok(true);
    })
  })
})

Testing

It has the following hooks

describe('hooks', function() {

  before(function() {
    // runs before all tests in this block
  });

  after(function() {
    // runs after all tests in this block
  });

  beforeEach(function() {
    // runs before each test in this block
  });

  afterEach(function() {
    // runs after each test in this block
  });

  // test cases
});

Testing

ChaiJS

Is a BDD / TDD assertion library 

I always prefer the BDD assertion style

expect(function () {}).to.not.throw();
expect({a: 1}).to.not.have.property('b');
expect([1, 2]).to.be.an('array').that.does.not.include(3);

API

Testing

Clone repo

https://github.com/rafinskipg/test-functional-boilerplate

Launch tests

npm test

Make tests go green.

You can submit a pull request with your implementation for further feedback

JavaScript functional

Write a maybe function

Write tests for your maybe function

JavaScript functional

Write a "once" function

Write tests for the once function

Final monster

Merge branch

 

git pull origin final-countdown

Discover new requirements

npm test

Make tests go green.

You can submit a pull request with your implementation for further feedback

Links

Functions

Scopes & Closures

 

Made with Slides.com