Coding Bootcamp Week 3: Recursion, Object Oriented Programming, Data Structures — Stacks & Queues

JavaScript Fundamentals

Reem Dalvi
5 min readJan 29, 2023

It has been a content heavy week, but my prefrontal cortex loves a challenge. I can see the benefits of using Test-Driven Development with every code written, not only does it ensure the intended functionality of the code but also allows for better understanding of concepts.

Recursion

It is an interesting concept to grasp, it becomes clearer and more comprehensible when it is explained in the context of its function within the call stack and the distinctions between global and local execution.

In recursion, multiple calls may build up on the call stack which operates on a last in, first out principle (LIFO) and waits for the base case to be met, then the previous calls can evaluate and resolve.

Base case + Recursive step + Recursive call.

// Recursively adding numbers from 1 to num

function sum (num) {
if (num === 1) return 1; // base case
return num + sum(num - 1); // recursion
};

Object-Oriented Programming (OOP)

We started with building factory function using TDD and completed a coding sprint on data structures — stacks and queues.

The principles of Object-Oriented Programming (OOP) in JavaScript are:

  1. Abstraction: Hiding the implementation details and exposing only the necessary information to the user.
  2. Encapsulation: Wrapping data and behavior within an object to protect its state from outside interference.
  3. Inheritance: Creating new objects based on existing objects, which can inherit properties and behavior.
  4. Polymorphism: Allowing objects to take on many forms, such as a single method having multiple implementations based on context.

OOP exploits the fact that objects in JavaScript can hold data in properties and hold ‘behaviours’ as methods/functions.

If we want to create lots of objects that all have the same basic blueprint, we can create a factory function. This function can return a new object every time it's called, where each one is initialised with the same template.

This keyword: represents the context of the function. Whenever a function is called as a method of an object, the this inside of it gets implicitly bound to whatever object is calling the function (i.e. the object left of the dot).

Example of factory function:

function factoryFn(name) {
const newUser = {}
newUser.username = name;
newUser.basket = [];
}

fuction addToBasket(item) {
this.basket.push(item)
}

const mandy = createUser("Mandy")
mandy.addToBasket('pear') // adds pear to basket

mandy is an instance of factoryFn and owner of the function addToBasket, so any occurrences of this within that function act as placeholder for the mandy object.

Prototypes

So in the example above, we can see that function addToBasket() is just floating around in the void so to encapsulate it, we can use prototype, a property of an object that allows you to share properties and methods among different instances of the same object.

const userPrototype = {
addToBasket: fuction (item) {
this.basket.push(item)
}
deleteLastItem: function () {
this.basket.pop()
}
}

function newUser(name) {
const newUser = Object.create(userPrototype)
newUser.username = name;
newUser.basket = [];
}

const mandy = newUser('Mandy')
mandy.addToBasket('pear')
mandy.deleteLastItem()
// mandy.basket would return []

The prototypal object called userPrototype has methods declared in there that are shared across all instances of the factory functions.

In order to assign this as a prototypal object for our factory functions we will make use of the Object.createmethod.

But then enters Class…

Class

Classes are syntactic sugar that abstracts away all of days 2 and 3 away. When we create a class, we also create a constructor within it, which is a method that is called when instantiating the class with the ‘new’ operator.

class User {
constructor(name) {
this.name = name;
this.online = false
}

greet() {
console.log('Hello', this.name)
}
}

const user1 = new User('Mandy')
user1.greet() // outputs 'Hello Mandy'

So now we have our ‘factory function’ and prototype all in the class and user1 is an instance of that class that has all the properties and methods from that class.

Classes can inherit and extend from other classes too.

Get & Set

A getter is a method used to retrieve the value of an object’s property and a setter is a method used to change the value of an object’s property.

class Person {
constructor(name) {
this._name = name;
}
get name() {
return this._name;
}
set name(newName) {
this._name = newName;
}
}

const person = new Person("John");
console.log(person.name); // outputs "John"
person.name = "Jane";
console.log(person.name); // outputs "Jane"

We can create private fields which cannot be accessed outside of the class declaration by using # name.

class TimeSheet {
#hoursWorked = 0;
#hourlyRate;
#shiftLength = 8;

constructor(name, hourlyRate) {
this.name = name;
this.#hourlyRate = hourlyRate;
}
}

davidsTimeSheet.name; // "David" - public field
davidsTimeSheet.hoursWorked; // undefined - private field

Links for the week

I am more of a visual/reading type of learner so I found referring to textbooks helped with the low-level understanding of how OOP worked.

Emotional/Limbic Check-In 👁🩸

I suffered with blurry vision by the end of this week, so I rotated my desk to face my window to use the 20–20–20 rule (every 20 minutes, look at something 20 feet away for 20 seconds).

The Pokémon game sprint was fun but I was paired with someone who had no intention of becoming a software developer or learning JS so we ended up with spaghetti code. I slithered my way out of the pairing and spent a decent amount of time untangling the mess but was able to implement the game in the end.

I really appreciate the complexity of video games. I am currently playing Cyberpunk 2077 and I find myself consistently delving into the thought processes behind the mechanics, striving to comprehend the logic that went into its creation.

computerSci.concat(biologySci) 🔗

Learning about Object-Oriented Programming has made me contemplate whether humans are merely instances of the class HomoSapiens, sharing similar experiences but executing our “methods” differently.

We all evolved from the same prototypic eukaryote cell and eventually diverged into various taxonomic categories.

This can be observed in our close relatives, the chimpanzees, with whom we share a 98.7% similarity in DNA, a result of the 1.3% divergence/polymorphesim that occurred when our species extended from a common ancestor (inheritance).

Just a philosophical analogy to help me understand the concept, or perhaps also highlighting similarities in structure and behaviour between the digital and physical realm.

Leap through time

--

--

Reem Dalvi

I like finding parallels between biological and computer science