JavaScript

Slack

JavaScript Syntax

First: The basics

Variable declaration

// ES5
var foo;
var bar;

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

What happens to let?

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

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

// i is not visible here

there are 2 types of scope. Local and global

Each function creates a new scope and it determines the visibility of these variables

Assignation

Variable assignation

// ES5
var foo = 4;
var bar = 'bar';

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

let salvame;
salvame = null;

let telecinco = null;

telecinco = 0;

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

Comparing values... 

Comparission

 

const x = 5;

x === 5; // Strict type and value
x == '5'; // Compare only value

// Not equal
x != '5'; 
x !== '5';

// Greater than
x > 3;
x >= 5;

Operators

 

 

 

               NaN... NaN

  Operators...

const x = 5;

x = 5 - 3 // 2
x = 5 * 2 // 10

x += 2 // 12
x *= 2 // 24
x /= 2 // 12
x %= 2 // 0
x++ // Increments 1
x-- // Decrements 1

x ** y // Exponentiation

  Operators...

const x = 5;

const y = -x // y === -5
const z = +y // z === 5

// Logical operators
// && and
(5 < 10 && 10 > 1)

// || or
(5 > 10 || 10 > 1)

// ! not
!false // true

// Ternary operator 
const a = x > 10 ? 'car' : 'house';

WAT

Comparission Common pitfails

// Common comparission pitfails
// Arrays instances are stored in differents parts of the memory
console.log([] == [])

// Objects too are different
console.log({} == {})

// Variables can point to the same reference of memory
var a,b;
a = b = {};
console.log(a == b);

// Double equal comparision will make javascript convert values to it's integer value
// And the number value of [] is 0 -> Number([])
// false, null, undefined, NaN, 0, '' and "" are considered falsy, and the number value of false is 0
console.log([] == false)

// Null with relational operators is casted to its Number value, 0
console.log(0 < null)

// This does not happen with the == operator
console.log(0 == null)

Comparission Common pitfails

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

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

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

// Is true
console.log(''  ==  false)
// Is false
console.log(''  === false)

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')

JavaS... TRICKS

// !! is used to produce a true/false based on truthy/falsy values
!!something

// Using OR to select the truthy value
const a = b || c

// Using AND as a safe accessor
if( a && a.method ) { 

}

// Conver to a number
let one = '1'
let numberOne = +one

fn()

Function declaration

// ES5
function suma (a, b) {
  return a + b
}

// ES6
const resta = (a, b) => a - b

Functions

 

=> 

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. Higher order functions & Higher order components 
  4. Lodash style
  5. Ramda
  6. Redux / RxJS ...

JavaScript can be functional

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

JavaScript can be functional

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

return functions

JavaScript can be functional

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

pass functions as arguments

JavaScript can be functional

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

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

even create new structures of control

JavaScript can be functional

Anonymous functions and lambda syntax () => x

x => x * 2


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

JavaScript can be functional

Closures. A function defined inside a function gets access to its variable binding

function creaSumador(x) {
  var movida = 'sumando';
  return function(y) {
    console.log(movida);
    return x + y;
  };
}

var suma5 = creaSumador(5);

JavaScript can be functional

JavaScript has the Array helpers, map, filter, find, reduce

JavaScript can be functional

Pure functions.
Functions that always return the same result given certain parameters. They never mutate the data.

JavaScript can be functional

Inmutability. For ensuring functional programming and avoiding side effects.

For example, we can create new objects with:

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

{
  ...myObj,
  ...newProperties
}

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)

JavaScript can be functional

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)

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

JavaScript can be functional

Partial application

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

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

const multiplyAndAdd = (a, b) => {
  return (c) => add(multiply(a,b), c)
}

multiplyAndAdd(3,2)(5)

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)

What is functional?

function composition

currying / partial application

inmutability

pure functions

 

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 

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


// Using ramda 
const sum10 = R.curry(suma)(10)

sum10(30) // 40
sum10(90) // 120

Currying

JavaScript functional - Level 1

Create a function that:

- Receives a user object and a property name (string)

- Returns a new user object with  that property setted to "test"

- Make the function curryfied or partial applied so you can pass different property parameters

JavaScript functional - Level 1

Spread operator

Let's you create a new object.

const user = {
  name: 'test',
  surname: 'pepito',
  email: '123@gmail.com'
}

const newUser = {
  ...user,
  email: '234@gmail.com
}

JavaScript functional - Level 1b

Change your previous function to use the new spread operator

Spread operator

It allows you to extract properties from an object (destructuring assignment)

 

const request = {
  headers: {},
  body: {
    name: 'test'
  },
  queryParams: {
    camaign: 'test'
  }
}

const { headers, ...noHeadersRequest } = request

JavaScript functional - Level 2

Create a function that:

- Receives 2 parameters, one is the user and the other is the new user data (object)

- Returns a new user object with the properties updated but remove at least 2 properties from the original user

 

JavaScript functional - Level 2

const user = {
  name: 'abc',
  email: 'test@test.com',
  address: {
    street: '1'
  },
  metadata: ['a', 'b', 'c']
}

myFunc(user, { email: 'email@email.com' })

/*
  {
    name: 'abc',
    email: 'email@email.com'
  }
*/

Spread operator

It allows you to concat arrays

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

const b = [0, ...a, 5, 6, 7, 8]

Spread operator

It allows you to extract properties from an array (destructuring assignment)

 

const colors = ['green', 'red', 'yellow', 'pink']

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

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)

Function Composition

 

Function composition is the ability to pass the result of one function to another.

const sum10 = (a) => a + 10
const multiplyBy5 = (b) => b * 5

console.log(sum10(multiplyBy5(10)))

const sumAndMultiply = R.compose(sum10, multiplyBy5)
console.log(sumAndMultiply(10))

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'
}]

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

JavaScript functional - Level 3 - Time 15 min

Create a script that combines the following techniques:

- Function composition

- Array map

- Spread operator

 

JavaScript functional - Level 3 - Time 15 min

const numbers = [2, 3, 4, 5, 6]

const result = myFunc(numbers)

/*
{
  first: 40,
  second: 60,
  rest: [40, 50, 60]
}

*/

A quick tip

We are going to learn about Function.prototype.apply && Function.prototype.call

Every JavaScript object has a prototype. The prototype is also an object.

All JavaScript objects inherit their properties and methods from their prototype.

A quick tip

We can call a function in 4 different ways.

myFunction(a);
obj['myFunction'](a);
myFunction.call(null, a)
myFunction.apply(null, [a])

JavaScript functional - Level 4 - Time 15 min

Create a function "partialApply" that: 

- Receives a function and N arguments and partially applies those arguments to the function

- Test your `partialApply` function with another function that receives N arguments

 

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

Javascript Avanzado - 1

By rafinskipg

Javascript Avanzado - 1

JavaScript Avanzado.

  • 601