Kunci jawaban 18 Latihan HTTP dan Form.

18.1 Negosiasi Konten

async function coba(tipe) {
  let resp = await fetch(URL, {headers: {Accept: tipe}});
  console.log(tipe, "→", await resp.text());
}
for (let tipe of ["text/plain", "text/html", "application/json"]) {
  coba(tipe);
}

Kenapa: header Accept memberi tahu server format yang kita inginkan; server yang mendukung negosiasi konten membalas dengan format berbeda untuk Accept berbeda. await resp.text() mengambil body sebagai string tiap kali. (Ingat fetch gak reject untuk status error — cek resp.ok di kode nyata.)

→ Soal: 18 Latihan HTTP dan Form > 18.1 Negosiasi Konten

18.2 Workbench JavaScript

let kode = document.querySelector("#kode");
let hasil = document.querySelector("#hasil");
 
document.querySelector("#jalankan").addEventListener("click", () => {
  let teks = kode.value;
  try {
    let keluar = Function(teks)();
    hasil.textContent = keluar === undefined ? "" : String(keluar);
  } catch (e) {
    hasil.textContent = String(e);
  }
});

Kenapa: Function(teks)() membuat fungsi dari string kode lalu menjalankannya — inti dari sebuah “runner”, sama seperti playground buku latihan ini. try/catch menangkap error sintaks maupun runtime dan menampilkannya, bukan meng-crash halaman. (Menjalankan kode dari string berbahaya kalau sumbernya tak tepercaya; buat mainan sendiri aman.)

→ Soal: 18 Latihan HTTP dan Form > 18.2 Workbench JavaScript

18.3 Game of Life

function generasiBerikut(grid, lebar, tinggi) {
  let baru = [];
  for (let y = 0; y < tinggi; y++) {
    for (let x = 0; x < lebar; x++) {
      let tetangga = 0;
      for (let dy = -1; dy <= 1; dy++) {
        for (let dx = -1; dx <= 1; dx++) {
          if (dx == 0 && dy == 0) continue;
          let nx = x + dx, ny = y + dy;
          if (nx >= 0 && nx < lebar && ny >= 0 && ny < tinggi
              && grid[ny * lebar + nx]) {
            tetangga++;
          }
        }
      }
      let hidup = grid[y * lebar + x];
      baru[y * lebar + x] =
        tetangga == 3 || (hidup && tetangga == 2);
    }
  }
  return baru;
}

Kenapa: grid disimpan sebagai array boolean datar (indeks y * lebar + x). Untuk tiap sel, hitung tetangga hidup (loop dy/dx dari -1 sampai 1, lewati sel sendiri, dan cek batas grid). Aturannya diringkas jadi satu ekspresi: sel jadi/tetap hidup kalau punya tepat 3 tetangga, atau sedang hidup dengan 2 tetangga. Yang penting: hasil ditulis ke array baru, bukan mengubah grid — kalau kamu ubah grid saat menghitung, sel yang sudah diperbarui akan salah memengaruhi tetangganya. Ini persis pelajaran “hitung nilai baru, jangan ubah yang lama”.

→ Soal: 18 Latihan HTTP dan Form > 18.3 Game of Life