Spodziewałem się, że ktoś zwróci uwagę na zmienne globalne. Tylko czy faktycznie można je pominąć w tym przypadku? Tutaj nie ma funkcji main(), którą mógłbym zapętlić. Z drugiej strony może faktycznie, całą logikę można ułożyć inaczej. Użyte zmienne to typy proste i z tego co widzę i rozumiem, w funkcjach przekazuje je jako wartość, a nie referencje. Stąd zamysł, by funkcje "dobierały" się do zmiennych globalnych bezpośrednio.
Tutaj zależy od podejścia, bo javascript pozwala na programowanie funkcyjne i obiektowe.
W podejściu funkcyjnym unikałbym modyfikacji zmiennych globalnych i jak najwięcej starałbym się korzystać z argumentów i słówka kluczowego return.
Wszystko po to, żeby unikać sytuacji jak niżej
let testValue = '';
function funcA() {
testValue = 'function-a';
funcB();
if (testValue === 'function-a') { // ten warunek nigdy się nie wykona, bo funkcja "funcB" modyfikuje globalnie zmienną "testValue"
console.log(`testValue ma wartość ${testValue}`);
} else {
console.log('testValue zostało zmienione w czasie trwania funkcji');
}
}
function funcB() {
testValue = 'function-b';
}
Obiektowo:
class Game {
static turn = 1;
static started = false;
static newTurn() {
// ...
}
}
class Board {
static fill() {
// ...
}
static clear() {
// ...
}
}
class Player {
constructor() {
// ...
}
move() {
// ...
}
}
const playerA = new Player();
const playerB = new Player();
Później na pewno dojdziesz do momentu, gdzie będziesz dzielić kod na kilka plików, dojdą jakieś moduły co powinno pomóc w lepszej organizacji projektu.
Na ten moment raczej nie ma sensu się tym przejmować tylko najlepiej dalej się uczyć składni języka
Początkowo event przypiąłem do tabelki. Ale efekt był taki, że po kliknięciu na daną komórkę (element td) łapało mi id elementu parent, czyli table. Dlatego zdecydowałem się podpiąć event pod każdy td.
No chyba, że istnieje sposób, by dostać się do childa.
Za każdym razem jak podpinasz jakiś event to do callbacka w addEventListener
jest przekazywany argument dotyczący eventu.
e.target
odnosi się do jakiegokolwiek elementu, który wywołał zdarzenie i w tym przypadku może być elementem td
, p
, lub span
.
Natomiast e.currentTarget
odnosi się zawsze do elementu, który ma przypisanie zdarzenie i w tym przykładzie jest to table
.
<table>
<tr>
<td>
TD 1
<p class="akapit">Akapit 1</p>
<span>Span 1</span>
</td>
<td>
TD 2
<p class="akapit">Akapit 2</p>
<span>Span 2</span>
</td>
<td>
TD 3
<p class="akapit">Akapit 3</p>
<span>Span 3</span>
</td>
</tr>
</table>
const table = document.querySelector('table');
table.addEventListener('click', (e) => { // pod parametrem "e" kryje się nasz event click
console.log(e.target.textContent); // e.target to jest element, który wywołał zdarzenie
// oczywiście możemy dokładniej sprawdzić, który element został kliknięty po przez różne atrybuty
console.log(e.target.classList.contains('akapit')); // tutaj sprawdzamy, czy element ma klasę "akapit"
console.log(e.target.tagName); // tutaj zostanie wyświetlona nazwa elementu
console.log(e.currentTarget) // nasza tabelka
})
Pewnie musiałbyś zmienić lekko strukturę gry żeby to działało, ale wspomniałem bardziej o tym w ramach takiej ciekawostki niż faktycznego błędu.
Taka drobna optymalizacja, bo przy dużych tabelach, gdzie byłoby kilkadziesiąt/kilkaset wierszy miałoby to większe znaczenie.