---
tags: ironhack, lecture,
---
<style>
.markdown-body img[src$=".png"] {background-color:transparent;}
.alert-info.lecture,
.alert-success.lecture,
.alert-warning.lecture,
.alert-danger.lecture {
box-shadow:0 0 0 .5em rgba(64, 96, 85, 0.4); margin-top:20px;margin-bottom:20px;
position:relative;
ddisplay:none;
}
.alert-info.lecture:before,
.alert-success.lecture:before,
.alert-warning.lecture:before,
.alert-danger.lecture:before {
content:"👨‍🏫\A"; white-space:pre-line;
display:block;margin-bottom:.5em;
/*position:absolute; right:0; top:0;
margin:3px;margin-right:7px;*/
}
b {
--color:yellow;
font-weight:500;
background:var(--color); box-shadow:0 0 0 .35em var(--color),0 0 0 .35em;
}
.skip {
opacity:.4;
}
</style>

# JS | Object Oriented Intro - Part 1 - objects, methods and `this` keyword
❓If you would like to see how to deal with prototypes using **constructor functions**, check these two lessons:
- [JS | Object Oriented Intro](http://learn.ironhack.com/#/learning_unit/6400)
- [JS | Prototypal inheritance](http://learn.ironhack.com/#/learning_unit/6401)
## Learning Goals
After this lesson you will be able to:
- Explain what Object Oriented Programming is
- Comprehend the importance of thinking about objects
- Create objects with the literal pattern
- Access properties of an object
- Use the `this` keyword
## Introduction
:::info lecture
La programmation orientée objet
{%youtube 5QjbX8GP1VM %}
:::
:::success
Official definition of [**object-oriented programming (OOP)**](https://en.wikipedia.org/wiki/Object-oriented_programming) is that it is a programming paradigm based on the concept of "objects", which can contain data, in the form of fields (often known as *attributes*), and code, in the form of procedures (often known as *methods*).
:::
Okay, so the main take away from this is - **objects** are the main key/tool/means of OOP. We will try to explain this through example.
## Monopoly
:::info lecture

Nous allons créer un jeu de Monopoly:
- 16 cases
- 3 joueurs
:::
In this lesson, we will create a very simple Monopoly game with 16 squares and 3 players. At every turn, a player launches one dice, moves forward and updates their cash based on the square's value.
You can see an example below illustrating the game we will create:
:::info lecture
Par ex, le 2 premiers tours :
:::

:::info lecture
En utilisant nos connaissances actuelles, voici comment nous pourrions écrire le programme :
:::
If we use *object literal* approach, which is the simplest approach we've seen so far, we could simulate the game the following way:
:::info lecture
On utilise un tableau pour stocker la valeurs de nos 16 cases :
:::
```javascript=
// Example of a VERY simple Monopoly game simulation
// Each square represents the cash earned when a player is on it. For example:
// - If a user is at position 0, the cash will increase by 100€
// - If a user is at position 4, the cash will decrease by 40€
const squares = [100,-10,0,0,-40,-10,-10,5,0,-10,-50,-10,0,0,-50,-10]
```
:::info lecture
On représente chacun des 3 joueurs par un objet `playerX` contenant les **infos propres** de chaque joueurs :
:::
```javascript=8
// --- Initialization ---
let player1 = {
name: 'Joaquim',
color: 'red',
position: 0,
cash: 1000
}
let player2 = {
name: 'Maxence',
color: 'blue',
position: 0,
cash: 1000
}
let player3 = {
name: 'Mostafa',
color: 'black',
position: 0,
cash: 1000
}
```
:::info lecture
Et c'est parti ! Player nÂş1 :
1. il lance le dé
2. `player1` avance du nombre de cases indiqué par le dé
3. il paye la case
4. on verifie qu'il n'a pas perdu (plus de cash)
et ainsi de suite pour les autres joueurs...
:::
```javascript=30
//
// --- Turn 1 ---
//
// --- Player 1 ---
// The dice is a random integer between 1 and 6
var dice = 1+Math.floor(6*Math.random());
// The position is always between 0 and 15 (the numbers of squares - 1)
player1.position = (player1.position + dice) % squares.length;
// The cash is updated based on the values of squares and player1.position
player1.cash += squares[player1.position];
// If the player doesn't have anymore cash, player is out of game
if (player1.cash < 0) {
console.log(`Game over for ${player1.name}.`);
}
// --- Player 2 ---
var dice = 1+Math.floor(6*Math.random());
player2.position = (player2.position + dice) % squares.length;
player2.cash += squares[player2.position];
if (player2.cash < 0) {
console.log(`Game over for ${player2.name}.`);
}
// --- Player 3 ---
var dice = 1+Math.floor(6*Math.random());
player3.position = (player3.position + dice) % squares.length;
player3.cash += squares[player3.position];
if (player3.cash < 0) {
console.log(`Game over for ${player3.name}.`);
}
// --- Display info ---
console.log(player1);
console.log(player2);
console.log(player3);
//
// --- Turn 2 ---
//
// --- Player 1 ---
var dice = 1+Math.floor(6*Math.random());
player1.position = (player1.position + dice) % squares.length;
player1.cash += squares[player1.position];
if (player1.cash < 0) {
console.log(`Game over for ${player1.name}.`);
}
...
```
:::info lecture
**AVANTAGES** d'écrire le programme ainsi:
- simple
- déclaratif
- flexible : on peut facilement changer les choses
:::
Using this simple approach has some **pros**:
- it's super convenient, straight-forward
- very flexible in a declaration
- very little code when declaring them
- you can create them at any point in your code and use them without a lot of previous set up
:::info lecture
**INCONVENIENTS**
Beaucoup de code est répété, comme par ex:
- pour chaque joueur, on a dû répété le nom de chq propriété alors qu'elles portent évidemment le même nom
- entre chaque tour, on répète les mêmes instructions pour chaque joueur
:::
However, this approach has some **cons** as well:
- **We don't have a fast way to create the object**. Instead, we always have to specify all the properties, which means a lot of copy pasting and making minor changes from object to object. (In our previous example, we are initializing the `position` to `0` and the `cash` to `1000`.)
- **We don't have any methods for our objects**. It would be nice to have a method `player.move()` instead of writing the same code again and again.
## Object methods and `this` keyword
:::info lecture
Comme nous avons vu qu'un objet pouvait contenir n'importe quel type de valeur, on va pouvoir définir une fonction `move` pour chaque joueur :
```javascript
let player1 = {
name: 'Joaquim',
color: 'red',
position: 0,
cash: 1000,
move: function() {
...
}
}
```
Probleme : comment depuis `move` accéder à `position`/`cash` (sans faire ré-écrire le nom de la variable `player1.position`) ?
:::
:::success lecture
`this` va nous permettre cela :
:::
Let's change our code to add 2 methods: `move()` and `displayInfo()`.
```javascript=
// Example of a VERY simple Monopoly game simulation
let squares = [100,-10,0,0,-40,-10,-10,5,0,-10,-50,-10,0,0,-50,-10]
// --- Initialization with methods ---
let player1 = {
name: 'Joaquim',
color: 'red',
position: 0,
cash: 1000,
move: function() {
let dice = 1+Math.floor(6*Math.random());
this.position = (this.position + dice) % squares.length;
this.cash += squares[this.position];
if (this.cash < 0) {
console.log(`Game over for ${this.name}.`);
}
},
displayInfo: function() {
console.log(`${this.name} is at position ${this.position} and has ${this.cash}€`);
}
}
let player2 = {
name: 'Maxence',
color: 'blue',
position: 0,
cash: 1000,
move: function() {
let dice = 1+Math.floor(6*Math.random());
this.position = (this.position + dice) % squares.length;
this.cash += squares[this.position];
if (this.cash < 0) {
console.log(`Game over for ${this.name}.`);
}
},
displayInfo: function() {
console.log(`${this.name} is at position ${this.position} and has ${this.cash}€`);
}
}
let player3 = {
name: 'Mostafa',
color: 'black',
position: 0,
cash: 1000,
move: function() {
let dice = 1+Math.floor(6*Math.random());
this.position = (this.position + dice) % squares.length;
this.cash += squares[this.position];
if (this.cash < 0) {
console.log(`Game over for ${this.name}.`);
}
},
displayInfo: function() {
console.log(`${this.name} is at position ${this.position} and has ${this.cash}€`);
}
}
```
:::info lecture
Chaque player définit maintenant lui-même sa propre fonction `move` qu'on peut appeler via (dot-notation) :
```javascript
player1.move();
```
:::
:::info lecture
Grâce à ca, nos tours sont bcp plus facile à écrire :
:::
```javascript=59
//
// --- Turn 1 ---
//
player1.move();
player2.move();
player3.move();
// --- Display info ---
player1.displayInfo();
player2.displayInfo();
player3.displayInfo();
//
// --- Turn 2 ---
//
player1.move();
player2.move();
player3.move();
// --- Display info ---
player1.displayInfo();
player2.displayInfo();
player3.displayInfo();
```
:::info lecture
Une fonction "rangée" dans un objet est appelée <b>une méthode</b> de cet objet.
:::
Let's analyze the new code and compare it to the previous one.
As we can see, the **code is more readable**, especially the part for "Turn 1" and "Turn 2".
:::info lecture
- `this` est un mot-clef du langage.
- à l'exécution d'une méthode, il aura pour valeur, l'objet qui porte cette méthode
:::
Our objects `player1`, `player2` and `player3` now have 2 extra properties: `move` and `displayInfo`. Both of them are functions, called **methods**, and they have a new keyword: **`this`**.
In this context, **`this`** refers to the current object. For `player1`, inside the `displayInfo`, `this.name` === `player1.name` === `Joaquim`.
:::success
When invoking a method on an object, **`this` becomes the object itself**.
:::
---
:::info lecture
Il nous reste un problème à règler : la répétition du code `move` de chaque player qui est en réalité le même !
On verra cela dans la P2...
:::
The last problem with have is that we don’t have a fast way to create the objects `player1`, `player2` and `player3`. We will solve this problem in the next lecture!
## Exercise with `this`
:::info lecture
<span style="font-size:500%;">🏋🏻‍♂️</span>
Codez les différentes méthodes :
- `.getAge()`
- `.addJoke()`
- `.getRandomJoke()`
de `chuck` :
:::
```javascript
// TODO: write the methods .getAge(), .addJoke() and .getRandomJoke()
let chuck = {
firstName: 'Chuck',
lastName: 'Norris',
birthDate: new Date('1940-03-10'),
jokes:[
'Chuck Norris counted to infinity... Twice.',
'Chuck Norris is the only man to ever defeat a brick wall in a game of tennis',
],
displayInfo: function() {
console.log('My name is ' + this.firstName + ' ' + this.lastName + ' and I have ' + this.jokes.length + ' jokes!')
},
getAge: function() {
// TODO
// Hint: to get the current time, you can do: new Date()
// Hint: you can subtract 2 dates and you get the number of milliseconds
},
addJoke: function(){
// TODO (don't return anything)
},
getRandomJoke: function() {
// TODO
},
}
chuck.displayInfo();
console.log('getAge', chuck.getAge()) ; // Should return 79 if you are in 2019
chuck.addJoke('Chuck Norris can divide by zero.');
console.log('getRandomJoke', chuck.getRandomJoke());
chuck.addJoke('Chuck Norris kills flies with his gun.');
console.log('getRandomJoke', chuck.getRandomJoke());
chuck.addJoke('Chuck Norris was once in a knife fight, and the knife lost.');
console.log('getRandomJoke', chuck.getRandomJoke());
chuck.displayInfo();
```
You can edit this Repl.it [note](https://repl.it/@MaxenceBouret/chuck-norris-oop).
## Summary
We've seen how to create methods (a function linked to an object) and we've seen the keyword **`this`** that refers to the current object.
## Extra resources
- [Learn OOP (video)](https://www.youtube.com/watch?v=O8wwnhdkPE4)
- [Object - fundamentals (video)](https://www.youtube.com/watch?v=PMfcsYzj-9M)