Back to the Basics: The Two Pillars in JavaScript

Last Modified
Last updated December 1, 2022

Intro

In order to understand the two pillars, we have to understand higher-order functions and functions vs objects.

Functions are Objects

Remember: when you invoke a function, you get this and arguments in the execution context.
// Different ways of calling functions function one() { return 1; } one(); const obj = { two: function() { return 2; }, altTwo() { return 2; } } obj.two(); function three() { return 3; } three.call(); const four = new Function('num', 'return num'); four(4);
// Functions are objects function woohoo() { console.log('woohoo'); } woohoo.yell = 'ahh'; // Illustration of what happens with functions const specialObj = { yell: 'ahh', name: 'woohoo', (): console.log('woohoo'); }
Functions are just objects… so we can pass them around like objects. We can store them as data, move them around, etc.
 
Functions are first class citizens in JS
What does this mean?
  1. Functions can be assigned to variables and properties of objects var stuff = function(){}
  1. Pass functions as arguments to other functions function a(fn) { fn() }
  1. Return functions as values from other functions
    1. function b() { return function c() { console.log('bye')} } b()();
 
These properties of functions allow JS to be a functional programming language.
Warnings:
  1. Avoid initializing functions inside loops
    1. Call it in the loop, instead of initializing it and calling it
  1. Avoid returning parameters/variables that don’t exist in functions
 

Higher Order Functions (HOF)

Higher Order Functions are functions that can take function as an argument OR a function that returns another function.
 
Why are they useful?
  • DRY
 
Example:
const multiplyBy => num1 => num2 => num1*num2 multiplyBy(4)(6)

Closures

Closures are a combination of functions and the lexical environment in which they are declared.
 
Example:
function a() { let grandpa = 'grandpa'; return function b() { let father = 'father'; return function c() { let son = 'son'; return `${grandpa} > ${father} > ${son}`; } } } a()()() // How did son (c) remember grandpa? const one = a(); // Should granpda be garbage collected when this runs?
 
function boo(string) { return function(name) { return function(name2) { console.log(`${string} ${name} ${name2}`); } } } const boo = string => name => name2 => console.log(`${string} ${name} ${name2}`); boo('hi')('tim')('becca'); const booString = boo('hi'); // wait 5 years (while running) const booStringName = booString('tim'); // hi would still be available 5 years later (if it kept running)

Prototypal Inheritance