Object-Oriented Programming in JavaScript
Almost everything element in JavaScript is an object, and we can make a beatbox machine in the module.
Object-Oriented Programming: What is it and why?
It's a way for us to organize software around data and objects. It's more-so about how you program and O-O programming combine related attributes and functions into container objects. An example is like a Google Home Mini Box with a container, and inside the container we have the actual Google Home Mini with attributes (color, shape, buttons, etc.) and these define its attributes. Functionality is like "What can this Google Home Mini Do?" These are all functions of a container object.
For example, a car is an object and it has attributes and methods (make, year, color, engine interior color) as attributes and (unlockCar() lockCar() startEngine() shutOffEngine() drive() park() reverse()) is the containers of all the methods and attributes that we can do.
Object - Oriented Programming Encourages Organization, Easier to Maintain, is Reusable, and allows us to build large applications (facebook, and google have billions of lines of code they have to maintain).
An object is the container of data and methods. You present the data in key and value pairs and you see multiple objects with data and methods or functions. We can then get into how we create one. Creating an object with user will use a bracket notation.
Here's the example of a string:
let user = {
firstName: "John",
lastName: "Davis",
}
Here we have created ourself an object and we can console.log(user).
Here's what we get:
If we want to extract the full name, aka "John Davis", here's what we do:
let user = {
firstName: "John",
lastName: "Davis",
setPassword: (user, password) => {
user.password = password;
},
getFullName: (user) => {
return `${user.firstName} ${user.lastName}`
}
}
console.log(user);
console.log(user.getFullName(user));
Now, you can also access the objects in a bracket notation, like (console.log(user["lastName"]);
If we have an array called "user Hobbies", then we can just do console.log(user["user Hobbies"][0]) etc. That's when we use bracket notation, as compared to dot notation. How do we check for insert property?
Let's check if there's a first name property. Just do
if("firstName" in user) {
console.log("first name exists");
}
if("randomAttr" in user) {
console.log("randomAttr exists);
} else {
console.log("randomAttr does not exist");
}
to loop in object we do:
we can't do for(let prop of user) won't work because prop is not an object. It's not a list. Instead we can do
for(let prop in user) which loops through the keys of the object. We should do bracket notation that "You need to find a certain notation" and user.prop wont work, you have to console.log(user[prop]). There are 2 ways to create an object, we can just do let user = new Object({pass in the object}).
Almost everything in JavaScript is an object and it's not clearly defined what "almost" means. We can do typeof.
For example, the typeof of this attribute is a string:
let firstName = "John"
typeof firstName
A primitive is something that doesn't have any methods.
we can do toString() and .length. A primitive type like string, also has a these properties. How come this primitive also has values like length();
If I go and create a function called prototype and I return typeof a specific object as follows:
String.prototype.myRealType = function() {
return typeof this;
}
the typeof lastname is a string but the .myRealType() is an object. When we want to use certain functions, this string is transformed really quickly to an object (this is called coercion). We call the myRealType to a string object. A string object contains all of the necessary methods. When we need to know the type, then it will convert to object at will, or remain primitive otherwise.
To create a class, we define a class like so:
Within a class, there is a constructor method, something that initializes the values.
Classes are part of every object oriented project. A class is a template for creating objects. They encourage reusability.
Let's say there's a car with make (variable) and other functions drive(horsepower) and unlock() and from this class we create an object called an Audi with.a make as Audi, drive(500) and again the unlock() method.
class User{
constructor(firstName, lastName, userHobbies) {
this.firstName = firstName;
this.lastName = lastName;
this.userHobbies = userHobbies;
}
getFullName = () => {
return `${this.firstName} ${this.lastName}`;
}
}
Now we can pass in the parameter
let John = new User["John", "Davis", ["soccer", "volleyball"]];
Then console.log(John) has the function as a user. Now adding a function is done above as well, and console.log(John.getFullName()); will print out "John Davis".
Next up, let's talk about class inheritance. It's a very close friend to classes, allowing use to extend the data and methods to other classes. We can have classes that extend other classes in this way. It has drive and unlock coming from the car and the two classes just merge together and as a result, are able to work together. The pickup class has these values, not the Car class.
Let's create a user and a class.
class User {
constructor(firstName, lastName, userHobbies) {
this.firstName = firstName;
this.lastName = lastName;
this.userHobbies = userHobbies;
}
getFullName = () => {
return `${this.firstName} ${this.lastName}`;
}
}
class AdminUser extends User {
setPassword = (password) => {
this.password = password;
}
let John = new User("John", "Davis", ["soccer", "volleyball"']);
let Chris = new AdminUser("Chris", "Chu", ["programming", "inventing])
}
The AdminUser has everything the user has AND MORE.
Now, let's make a beatbox application.
We need to make up a module 7 folder. We can install a live server and click on index.html and click "go live" below" in a port.
Let's make this component of the server:
Let's delve into the index.html module first:
<!DOCTYPE html>
<head>
<meta charset = "utf-8">
<meta http-equiv="X-UA-Compatible" content = "IE=edge">
<title>BeatBoxJS</title>
<meta name = "description" content = "">
<meta name = "viewport" content = "width=device-width, initial-scale=1">
<link rel = "stylesheet" href = "./style.css">
</head>
<body>
<div class = "beatbox">
<div class = "beat">
<div id = "65" class = "button">A</div>
</div>
<div class = "beat">
<div id = "65" class = "button">S</div>
</div>
<div class = "beat">
<div id = "65" class = "button">D</div>
</div>
<div class = "beat">
<div id = "65" class = "button">F</div>
</div>
<div class = "beat">
<div id = "65" class = "button">G</div>
</div>
<div class = "beat">
<div id = "65" class = "button">H</div>
</div>
<div class = "beat">
<div id = "65" class = "button">J</div>
</div>
<div class = "beat">
<div id = "65" class = "button">K</div>
</div>
<div class = "beat">
<div id = "65" class = "button">L</div>
</div>
</div>
</body>
</html>
and here's the css:
A flex container expands items to fill available free space or shrinks them to prevent overflow.
The flex-wrap CSS property sets whether flex items are forced onto one line or can wrap onto multiple lines. If wrapping is allowed, it sets the direction that lines are stacked.
body {
margin: 0;
}
.container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.beatbox {
width: 600px;
height: 600px;
background: #333;
border-radius: 20px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: space-evenly;
}
.beat {
width: 150px;
height: 150px;
flex-basis: 29%;
justify-content: center;
align-items: center;
}
.beat .button {
width: 120px;
height: 120px;
border-radius: 10px;
border: 5px solid aqua;
color: white;
display: flex;
justify-content: center;
align-items: center;
font-family: sans-serif;
font-size: 2em;
}
The CSS justify-content property defines how the browser distributes space between and around content items along the main-axis of a flex container, and the inline axis of a grid container. In this case, it's the X axis.
let beats = {
"65": {
beat: new Beat("./assets/Piano Chord 331.mp3"),
},
"83": {
beat: new Beat("./assets/Piano Chord 209.mp3"),
},
"68": {
beat: new Beat("./assets/Piano Chord 208.mp3"),
},
"70": {
beat: new Beat("./assets/Drum Sticks Hit 3.mp3"),
},
"71": {
beat: new Beat("./assets/Drum Snare Roll.mp3"),
},
"72": {
beat: new Beat("./assets/PREL Musical 57.mp3"),
},
"74": {
beat: new Beat("./assets/Cymbal Suspended 2.mp3"),
},
"75": {
beat: new Beat("./assets/Musical Compos 33.mp3"),
},
"76": {
beat: new Beat("./assets/Musical Orches 4.mp3"),
}
}
/**
* Function to play the beat upon a press of key
* HINT: use the keyCode
*/
triggerBeat = (event) => {
}
/**
* Keydown listener to fire triggerBeat function
* HINT: Log the keyCode of the key
*/
Let's look at what we have. We have a container and a beatbox container (the black box) and the buttons and those buttons represent the actual button. You might be thinking "What are these buttons for?" There's a utils file and script.js file. Now, let's look at utils.
/**
* Beat class that keeps track of playing the audio
* HINT: Make sure to pass in the audioSrc as parameter to create a new audio track
* HINT: Create a play function to play the audio if called
*/
class Beat {
}
/**
* Button class that keeps track of the button color based on a press
*/
class Button {
constructor(color, keyCode){
}
/**
* Set the button color based on color specified
*/
setButtonColorInHTML = () => {
}
/**
* Select function to set the background color and boxShadow
*/
select = () => {
}
/**
* Deselect function to reset background color and boxShadow
*/
deselect = () => {
}
}
The triggerBeat() function triggers the actual and the listener listens to the actual keys to be able to perform this sort of logic.
We want to create a listener for a keycode, and how do we do this? We add an even listener!
document.addEventListener('keydown', (event) => {
console.log(event);
})
The even contains the key code and then we can figure out what key is being preessed as a result. This is how we go ahead and mark the todo done.
class Beat {
constructor(audioSrc){
this.audio = new Audio(audioSrc)
}
play = () => {
this.audio.currentTime = 0;
this.audio.play()
}
}
Now,
triggerBeat = (event) => {
console.log(event);
}
/**
* Keydown listener to fire triggerBeat function
* HINT: Log the keyCode of the key
*/
document.addEventListener('keydown', (event, triggerBeat) => {
console.log(event);
})
This would log the event into the trigger beat function.






Comments
Post a Comment