アクセス・個数・追加を ▶ 実行して確かめましょう(先頭は 0 番)。
const fruits = ['りんご', 'みかん', 'ぶどう'];
// りんご(0番)
console.log('先頭:', fruits[0]);
console.log('個数:', fruits.length);
// 末尾に追加
fruits.push('もも');
console.log(fruits);
同じ処理を何度も書くのは大変。for 文でまとめて繰り返します。
for (初期化; 続ける条件; 毎回の更新)。定番は let i = 0; i < n; i++(0 から n 回)。
例として 1 から 10 までの合計を求めます。
for (let i = 0; i < 10; i++) {
// i = 0,1,...,9 で本体を繰り返す
}
▶ 実行して 1 から 10 までの合計を求めます。範囲(i <= 10)を変えてみましょう。
let sum = 0;
for (let i = 1; i <= 10; i++) {
// 1, 2, 3, … を足していく
sum += i;
}
// 55
console.log('1から10までの合計:', sum);
配列の各要素を順に処理したいときは forEach が読みやすいです。
各要素を受け取る関数(コールバック)を渡すと、要素の数だけ順に呼ばれます。
index を気にせず書けるのが利点です。
配列.forEach((要素) => {
// 各要素に対する処理
});
各要素が偶数か奇数かを ▶ 実行して判定します。
const nums = [3, 8, 15, 20];
nums.forEach((n) => {
console.log(n, n % 2 === 0 ? '偶数' : '奇数');
});
(n) => { ... } がコールバック関数。「関数を値として渡す」書き方で、次章でくわしく扱います。
チェックポイント
if / 三項演算子で分岐できるlength や push を使える(index は 0 始まり)for / forEach で繰り返し処理できる次は、処理に名前をつけて まとめて再利用 します。
関数 ・ 無名・アロー関数 ・ オブジェクト ・ Optional Chaining ・ クラス
処理やデータに「名前」をつけて、まとめたり再利用したりします。
一連の処理に名前をつけ、何度でも呼び出せるのが関数です。function で定義し、
( ) の引数で値を受け取り、return で返り値を返します。
実は console.log() も関数呼び出しの一種でした。
function 関数名(引数1, 引数2) {
// 処理
return 返り値;
}
// 呼び出し
関数名(値1, 値2);
足し算する関数を ▶ 実行。引数を変えて何度でも呼び出せます。
function add(a, b) {
return a + b;
}
// 5
console.log(add(2, 3));
// 6
console.log(add(10, -4));
名前のない関数(無名関数)も書けます。特に短い アロー関数 (引数) => 処理 が頻出です。
JS では関数も「値」。変数に入れたり、他の関数へ引数として渡す(コールバック)ことができます。
forEach や setTimeout に渡していたのが、まさにこれです。
// アロー関数を変数へ
const square = (x) => x * x;
// 関数を引数として渡す
setTimeout(() => { ... }, 1000);
アロー関数と、関数を渡すコールバックを ▶ 実行して確かめましょう。
// アロー関数を変数へ
const square = (x) => x * x;
// 25
console.log(square(5));
// 関数を引数として渡す(コールバック)
setTimeout(() => console.log('1秒後に実行'), 1000);
console.log('先に進む');
関連する値を「キー: 値」の組(プロパティ)でまとめたのがオブジェクト。{ } で作ります。
アクセスは obj.key(ドット記法)または obj['key'](ブラケット記法)。
あとからプロパティを追加することもできます。
const user = { name: 'じぐ太郎', age: 20 };
// アクセス
user.name
user['age']
// 追加
user.hobby = '釣り';
アクセスと追加を ▶ 実行して確かめましょう。
const user = { name: 'じぐ太郎', age: 20 };
// ドット / ブラケット記法
console.log("user.name: "user.name);
console.log("user[age]: "user['age']);
// 後から追加できる
user.hobby = '釣り';
console.log(user);
存在しないプロパティは undefined。そのさらに先をたどるとエラーになります。
Optional Chaining ?. を使うと、途中が無ければエラーにせず undefined を返して安全に止まります。
API の応答や、入力が任意のフォームなど「あるか分からない値」を扱うときに重宝します。
// a が無ければ undefined(.b でエラーにしない)
obj.a?.b
?. の有無で挙動がどう変わるか、▶ 実行して確かめましょう。
const user = { name: 'じぐ太郎' };
// 名前: じぐ太郎
console.log(`名前: ${user.name}`);
// 住所: undefined(存在しない)
console.log(`住所: ${user.address}`);
// console.log(user.address.city);
// 市区町村: undefined(?. なら安全)
console.log(`市区町村: ${user.address?.city}`);
同じ構造のデータと操作をまとめる設計図がクラスです。class で定義し、new で
実体(インスタンス)を作ります。
プロパティ(データ)とメソッド(関数)を持ち、メソッド内の this はそのインスタンス自身を指します。
class 名前 {
プロパティ = 初期値;
メソッド() { /* this.プロパティ で自分を参照 */ }
}
const 実体 = new 名前();
カウンターのクラスを ▶ 実行。new で作った実体が状態(count)を持ちます。
class Counter {
count = 0;
increment() { this.count++; }
}
const c = new Counter();
c.increment();
c.increment();
// 2
console.log('count:', c.count);
チェックポイント
いよいよ最後。時間のかかる処理を扱う 非同期 とブラウザ API です。
同期と非同期 ・ setTimeout ・ Promise ・ async / await ・ ブラウザ API
「時間のかかる処理」を上手に扱う非同期処理と、ブラウザの便利機能に触れます。
Promise / async / await で待つ処理を書けるlocalStorage や位置情報などブラウザ API を知るサーバーへの問い合わせなど時間のかかる処理を待つ間、他を止めないための考え方が非同期です。
setTimeout(関数, ミリ秒) は「指定ミリ秒後に、この関数を実行して」と予約する仕組みです。
予約したらすぐ次の行に進む(=非同期)ので、あとに書いた処理が先に動きます。出力の順番に注目。
// 1秒後の実行を予約し、すぐ次へ
setTimeout(() => { ... }, 1000);
順番が A → B → C になるのを ▶ 実行して体感しましょう。
console.log('A: 開始');
setTimeout(() => console.log('C: 1秒後に実行'), 1000);
// 非同期なので C より先に出る
console.log('B: 待たずに次へ');
「あとで結果が返る約束」が Promise。料理を注文して番号札をもらうように、結果は後から届きます。
resolve(値) が呼ばれたreject(理由) が呼ばれた.then(値 => …)(成功)と .catch(err => …)(失敗)で処理.then() は新しい Promise を返すので、.then().then() と数珠つなぎにできる0.5 秒後に結果が返る Promise を .then() で受け取ります。▶ 実行すると「先に進む」が先に出ることにも注目。
const wait = (ms) => new Promise((resolve) => {
setTimeout(() => resolve('完了!'), ms);
});
wait(500).then((msg) => console.log('then:', msg));
console.log('先に進む');
確認 出力は「先に進む」→「then: 完了!」の順。この処理を次のスライドで await に書き直します。
async を付けた関数の中では await が使えます。await 式 は、その Promise が解決するまで
その行で待ってから次へ進みます。非同期を同期のように読めるのが利点です。
失敗は try { ... } catch (e) { ... } で受けます(then/catch の catch に相当)。
async function f() {
// 解決を待ってから次へ
const v = await 何かのPromise;
// v を使う
}
5-4 と同じ処理を await で書き直したもの。▶ 実行して見比べましょう。
const wait = (ms) => new Promise((resolve) => {
setTimeout(() => resolve('完了!'), ms);
});
async function main() {
const msg = await wait(500);
console.log('await:', msg);
}
main();
console.log('先に進む');
確認 .then((msg) => …) が const msg = await wait(500) に変更。
ブラウザ自身が持つ機能(API)も使えます。今日は代表的な 2 つを紹介します。
localStorage … キーと値をブラウザに保存(ページを閉じても残る)。値は必ず文字列で保存されるlocalStorage.setItem('age', 20) としても、取り出すと文字列 '20'。数値に戻すなら Number(...) を使います。
この 2 つはこのスライドの実行環境では動きません(安全のためストレージ・位置情報を制限)。
手元のブラウザの Console に貼って試してみましょう。
// 保存と取り出し(値は必ず「文字列」で保存される)
localStorage.setItem('name', 'じぐ太郎');
console.log(localStorage.getItem('name'));
// 現在地の取得(ユーザーの許可が必要)
navigator.geolocation.getCurrentPosition((pos) => {
console.log(pos.coords.latitude, pos.coords.longitude);
});
チェックポイント
Promise(then/catch)と async/await で待つ処理を書けるlocalStorage など、ブラウザ API の存在を知っている要素の取得 ・ クリックイベント ・ 表示を変える ・ 見た目を変える ・ アニメーション
これまでの JS を使って、ページ(HTML)をクリックで動かしてみます。
transition で変化をなめらかに見せるページの要素は document.querySelector(セレクタ) で取得します(セレクタは CSS と同じ書き方)。
取得した要素に addEventListener('click', 関数) を付けると、クリックのたびにその関数が呼ばれます。
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
// クリックされたときの処理
});
ボタンを押すたびにコンソールへ出力します。▶ 実行してボタンを押してみましょう。
<button id="btn">押してね</button>
<script>
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
console.log('クリックされました');
});
</script>
取得した要素の textContent を書き換えると、画面の文字が変わります。
const out = document.querySelector('#out');
out.textContent = '新しい文字';
記述 押した回数を表示します。文言や増え方を書き換えて ▶ 実行 してみましょう。
<button id="btn">カウント</button>
<p id="out"></p>
<script>
let count = 0;
const out = document.querySelector('#out');
document.querySelector('#btn').addEventListener('click', () => {
count++;
out.textContent = count + ' 回押しました';
});
</script>
要素.style.プロパティ で CSS も書き換えられます(プロパティ名は backgroundColor のようにキャメルケース)。
out.style.backgroundColor = '#ffcdd2';
押すたびに背景色が切り替わります。▶ 実行して試しましょう。
<style>
#out {
padding: 10px;
border-radius: 6px;
}
</style>
<button id="btn">押す</button>
<p id="out">ここが変わる</p>
<script>
const colors = ['#ffcdd2', '#c8e6c9', '#fff9c4'];
let n = 0;
const out = document.querySelector('#out');
document.querySelector('#btn').addEventListener('click', () => {
n++;
out.textContent = n + ' 回';
out.style.backgroundColor = colors[n % 3];
});
</script>
CSS の transition を付けておくと、style で値を変えたときなめらかに変化します。
#box {
/* すべての変化を 0.3 秒でなめらかに */
transition: all 0.3s ease;
}
ボタンを押すと箱が四隅を移動します。transition のおかげでスッと動きます。▶ 実行。
<style>
#field {
position: relative;
width: 220px;
height: 220px;
border: 2px solid #999;
}
#box {
position: absolute;
top: 0;
left: 0;
width: 80px;
height: 80px;
background: #f06292;
color: #fff;
display: grid;
place-content: center;
transition: all 0.3s ease;
}
</style>
<button id="btn">動かす</button>
<div id="field"><div id="box">0</div></div>
<script>
let i = 0;
const box = document.querySelector('#box');
document.querySelector('#btn').addEventListener('click', () => {
i++;
box.textContent = i % 4;
box.style.top = [0, 1].includes(i % 4) ? '0' : '140px';
box.style.left = [0, 3].includes(i % 4) ? '0' : '140px';
});
</script>
チェックポイント
querySelector で要素を取得し、addEventListener('click', ...) でクリックを受け取れるtextContent / style でページの表示・見た目を書き換えられるtransition で変化をなめらかに見せられるHTML(構造)× CSS(見た目)× JavaScript(動き)で、ページが動くようになりました。
さっき作った自己紹介サイトを、Claude Code を相棒に JavaScript でよりリッチに。
小さな部品が出そろいました。あとはこれらを組み合わせるだけで、アプリが作れます。
今日触れなかった機能もたくさんあります。作りながら調べて足していきましょう。
============================================================================ JavaScript を始めよう(勉強会スライド) ビルド: npx marp slide.md --html -o slide.html --allow-local-files --theme-set themes/jig.css ============================================================================
↓ 演習タイマーの実装。題材を問わずそのまま使う。触らないでください。 各スライドに <div class="timer-box" data-seconds="秒数">…</div> を置くと右上にタイマーが出ます。 クリックで開始/停止、右クリックでリセット、± ボタンで 60 秒単位の増減。
↓ コードブロックにコピーボタンを付ける。題材を問わずそのまま使う。触らないでください。 各 <pre> の右上に「コピー」が出て、コード全文をクリップボードにコピーします(@@ ハイライトの記号は含まれません)。
↓ インライン playground(その場で試せるミニ実行環境)。題材を問わずそのまま使う。触らないでください。 スライド本文に次のように書くと、編集→実行できる小さな実行環境になります(詳細は TEMPLATE_GUIDE.md): <div class="playground" data-mode="console"> ```js console.log("hello"); ``` </div> data-mode="console"(既定)は console.log の出力を、data-mode="dom" は HTML の描画結果+console を表示。 data-height="120" で出力領域の高さ(px)を調整できます。コードは sandbox iframe(allow-scripts のみ)内で実行され、 さらに CSP で外部通信を遮断しているため、スライド本体にも外部にも影響しません。