Chore Door Step 61 - Why does this work?


#1

Hi Everyone,

I have a functioning Chore Door code but I still struggle to understand step 61. Here is the code:

let botDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/robot.svg”;

let beachDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/beach.svg”;

let spaceDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/space.svg”;

let closedDoorPath = “https://s3.amazonaws.com/codecademy-content/projects/chore-door/images/closed_door.svg”;

let startButton = document.getElementById(‘start’);

let currentPlaying = true;

let numClosedDoors = 3;

let openDoor1;
let openDoor2;
let openDoor3;

let randomChoreDoorGenerator = () => {
let choreDoor = Math.floor(Math.random()*numClosedDoors);
if (choreDoor === 0) {
openDoor1 = botDoorPath;
openDoor2 = beachDoorPath;
openDoor3 = spaceDoorPath;
} else if (choreDoor === 1) {
openDoor1 = beachDoorPath;
openDoor2 = botDoorPath;
openDoor3 = spaceDoorPath;
} else if (choreDoor === 2) {
openDoor1 = spaceDoorPath;
openDoor2 = beachDoorPath;
openDoor3 = botDoorPath;
}
}

let doorImage1 = document.getElementById(‘door1’);
doorImage1.onclick = () => {
if (currentPlaying === true && isClicked(doorImage1) === false) {
doorImage1.src = openDoor1;
playDoor(door1);
}
}

let doorImage2 = document.getElementById(‘door2’);
doorImage2.onclick = () => {
if (currentPlaying === true && isClicked(doorImage2) === false) {
doorImage2.src = openDoor2;
playDoor(door2);
}
}

let doorImage3 = document.getElementById(‘door3’);
doorImage3.onclick = () => {
if (currentPlaying === true && isClicked(doorImage3) === false) {
doorImage3.src = openDoor3;
playDoor(door3);
}
}

let startRound = () => {
doorImage1.src = closedDoorPath;
doorImage2.src = closedDoorPath;
doorImage3.src = closedDoorPath;
numClosedDoors = 3;
startButton.innerHTML = ‘Good luck!’;
currentPlaying = true;
randomChoreDoorGenerator();
}

startButton.onclick = () => {
if (currentPlaying === false) {
startRound();
}
}

const gameOver = (status) => {
if (status === ‘win’) {
startButton.innerHTML = ‘You win! Play again?’;
} else {
startButton.innerHTML = ‘Game over! Play again?’;
}
}

let isBot = (door) => {
if (door.src === botDoorPath) {
return true;
} else {
return false;
}
}

const isClicked = door => {
if (door.src === closedDoorPath) {
return false;
} else {
return true;
}
}

const playDoor = (door) => {
numClosedDoors–;
if (numClosedDoors === 0) {
gameOver(‘win’);
currentPlaying = false;
} else if (isBot(door)) {
gameOver(‘lose’);
currentPlaying = false;
}
}

startRound();

What I don’t understand: several functions (isClicked, isBot, gameOver) use the ‘door’ parameter and we pass into all of them door1, door2, door3 as arguments (see .onclick() functions.) Why does this work? In my code, there is no variable or function that defines door1 or door2 or door3. Instead, I have stuff like doorImage1, openDoor1 and the like. How come the door1, door2, door3 values are defined and instructing the programme to do what it’s supposed to?

Thank you for giving this a thought. JS is quite mysterious. Sometimes, it’s splitting hairs and sometimes it seems too forgiving.


#2

I totally agree. Its a double edged sword.

The reason you can use the variable door inside those functions is because you give them when you call the function.

let isBot = (door) => {
  if (door.src === botDoorPath) {
    return true;
  } else {
    return false;
  }
}

In this example. door is a scoped variable in the function. This means you can not use door ourtside of the function. It also means the function always needs a parameter given when you call this function.

Try for example calling door outside the function. or calling the function without a parameter. This should cause an error.

So door in those functions is equal to the parameter you give once you call the function.
if you call the function isBot(door3) door would be equal to door3

In your case it is the function playDoor(door3) that sets door.
Because playDoor(door3) calls the function isBot(door) and since playDoor(door3) names the incomming parameter door, isBot(door) accepts this parameter and names it the same because of this part = (door) =>
but in the end door = door3