Function properties and methods

var person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person1 = {
firstName:"John",
lastName: "Doe"
}
var person2 = {
firstName:"Mary",
lastName: "Doe"
}
person.fullName.call(person1); // Will return "John Doe"

Immediately Invoked function expressions (IIFE or 'iffy')

(function(){
const temp = 'World';
console.log(`Hello ${temp}`);
})();
// 'Hello World'


// this function has two blocks, same var name that run independently
(function() {
// block A
const name = 'Block A';
console.log(`Hello from ${name}`);
}());
(function() {
// block B
const name = 'Block B';
console.log(`Hello from ${name}`);
}());
// Hello from Block A
// Hello from Block B

Self-defining functions

function party(){
// this one runs console.log('Wow this is amazing!');
party = function(){
// then when it is set to a variable it only returns this new definition console.log('Been there, got the T-Shirt');
}
}

const beachParty = party; // note that the party function has not been invoked
beachParty(); // the party() function has now been redefined, even though it hasn't been called explicitly
// 'Wow this is amazing!'
party();
// 'Been there, got the T-Shirt'
beachParty(); // but this function hasn't been redefined
// 'Wow this is amazing!'
beachParty(); // no matter how many times this is called it will remain the same
// 'Wow this is amazing!'

// Losing properties ***************** party.music = 'Classical Jazz'; // set a property of the function
party();
// "Wow this is amazing!"
party.music; // function has now been redefined, so the property doesn't exist
// undefined

Recursive functions


function factorial(n) {
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1); // keeps going until it reaches the condition
}
}

Callbacks


Chapter 4. You’ll recall that they’re functions passed to other functions as arguments and then invoked inside the function they are passed to
****** remember nested callbacks can be ugly ******* function sing(song,callback) {
console.log(`I'm singing along to ${song}.`);
callback();
}

function dance() {
console.log("I'm moving my body to the groove.");
//( We’re just logging a simple message to the console in these examples, but these functions could be used to do anything in a practical sense.)
}

sing('Let It Go',dance);

// 'I'm singing along to Let It Go.'
// 'I'm moving my body to the groove.'

Promises


A promise represents the future result of an asynchronous operation
Promises don't do anything that can't already be achieved using callbacks,
but they help simplify the process, and avoid the convoluted code that can
result from using multiple callbacks.


const promise = new Promise( (resolve, reject) => {
// initialization code goes here
if (success) {
resolve(value);
} else {
reject(error);
}
});
returning one of two outcomes:
Resolved ― the asynchronous operation was completed successfully.
Rejected ― the asynchronous operation didn’t work as expected, wasn't successfully completed or resulted in an error.
// an example

const dice = {
sides: 6,
roll() {
return Math.floor(this.sides * Math.random()) + 1;
}
}
console.log('Before the roll');
const promise = new Promise( (resolve,reject) => {
const n = dice.roll();
setTimeout(() => {
(n > 1) ? resolve(n) : reject(n);
}, n*1000);
});
promise.then( result => console.log(`I rolled a ${result}`) ) .catch( result => console.log(`Drat! ... I rolled a ${result}`) );
console.log('After the roll');

Async functions


Allowing more than one process to happen (still single threaded though), and more importantly out of order - callbacks can handle some of this too.
function wait(message, callback, seconds){
setTimeout(callback,seconds * 1000);
console.log(message);
}
function selfDestruct(){
console.log('BOOOOM!');
}

invoke the wait() function then log a message to the console, we can see how JavaScript works asynchronously:
wait('This tape will self-destruct in five seconds ... ', selfDestruct, 5);
console.log('Hmmm, should I accept this mission or not ... ?');
// 'This tape will self-destruct in five seconds ... '
// 'Hmmm, should I accept this mission or not ... ? '
// 'BOOOOM!'

Functions that return functions


// this one uses eval() that will give the scope valuation of a string.
const x = 1;
function evalAndReturnX(code) {
eval(code);
return x;
}


console.log(evalAndReturnX("var x = 2"));
// → 2
console.log(x);
// → 1


// this is a function constructor that takes in the comma separated arguements and following is the function - no scope problems here
let plusOne = Function("n", "return n + 1;");
console.log(plusOne(4));
// → 5
*****************************
function greeter(greeting = 'Hello') {
return function() {
console.log(greeting);
}
}
const englishGreeter = greeter();
englishGreeter();
// Hello
const frenchGreeter = greeter('Bonjour');
frenchGreeter();
// Bonjour
const germanGreeter = greeter('Guten Tag');
germanGreeter();
// Guten Tag

Closures


Closures are one of JavaScript’s most powerful features
Functions declared from within another function have access to any variables declared in the outer function’s scope.

function outer() {
const outside = 'Outside!';
function inner() {
const inside = 'Inside!';
console.log(outside);
console.log(inside);
}
return inner;
}
const closure = outer(); // now assign a variable to the return value of the outer() function
It now has access to the variables created insideboththe outer() and inner() functions
closure();
// Outside!
Inside!
// This allows some skirting around scope and gives access to inside variables.
function closure() {
const a = 1.8;
const b = 32;
return c => c * a + b;
}
const toFahrenheit = closure();
toFahrenheit(30); // 86

Introduction to functional programming


JavaScript has always supported functional-style programming due to functions being first-class objects.
The ability to pass functions as arguments, return them from other functions, and use anonymous functions
and closures, are all fundamental elements of functional programming that JavaScript excels at.
PURE FUNCTIONS
1. return value of a pure function should only depend on the values provided as arguments
2. There are no side-effects. A pure function doesn't change any values or data elsewhere in the program.
3. Referential transparency. Given the same arguments, a pure function will always return the same result.
// example
function reverse(string) {
return string.split('').reverse().join('');
}
const message = 'Hello JavaScript';
reverse(message); // 'tpircSavaJ olleH'
message // hasn't changed // 'Hello JavaScript'

Currying


Currying allows you to turn a single function into a series of functions instead.
This is useful if you find that you’re frequently calling a function with the same argument.
For example, the following multiplier() function is a generic function that returns the product of two numbers that are provided as arguments:

function multiplier(x,y) {
return x * y;
}
// calculate a tax rate of 22% on a £400 sale using 0.22 and 400 as arguments
const tax = multiplier(0.22,400); // 88

// code at the start that allows it to be curried
function multiplier(x,y) {
if (y === undefined) {
return function(z) {
return x * z;
}
} else {
return x * y;
}
}

Chapter Summary



* Functions have built-in properties such as length , but can have custom properties added.
* All functions have call() and apply() methods that can invoke a function with the value of this bound to an object that is provided as an argument.
* Immediately Invoked Function Expressions or IIFEs are functions that are enclosed in parentheses and immediately followed by double parentheses so they’re invoked. They are useful for namespacing variables and setting default values.
* Functions are able to dynamically redefine themselves in the body of the function, depending on certain conditions.
* A recursive function will keep invoking itself until a certain condition is met.
* A callback is a function that’s provided as an argument to another function.
* Callbacks are frequently used in asynchronous programming as part of the event loop. This means that a program can continue to run in a single thread while waiting for another task to be completed.
* Promises can be used instead of callbacks to deal with multiple asynchronous actions in sequence. They also provide a nicer mechanism for handling errors.
* Functions that return other functions are known as higher-order functions.
* A closure is the process of keeping a reference to a variable available outside the scope of the function it was originally defined in.
* A generator is created by placing an asterisk character (*) after the function keyword.
* A generator function will return an iterator object that provides a next() method, which returns the next value in a sequence that is defined in the generator function.
* unctional programming involves breaking processes down into steps that can be applied as a series of functions.
* Pure functions are functions that don't rely on the state of the code they are called from, have no side-effects, and always give the same result when given the same arguments (referential transparency).
* Currying or partial application is the process of applying one argument at a time to a function. A new function is returned until all the arguments have been used.