【JS初級者向け完全ガイド】
─────────────────────────────────────────────
「なんとなくJSを書いたことはあるけど、毎回ググってばかり…」
「コードを読んでいると見慣れない書き方が出てきて混乱する」
そんな人のために、実際の開発で頻繁に登場する構文を厳選してまとめました。
「なんとなく動いている」から「意味を理解して書ける」に一歩進みましょう。
この記事で扱う構文
- 変数宣言(const / let)
- テンプレートリテラル
- アロー関数
- 分割代入
- スプレッド構文 / レスト構文
- 配列操作(map / filter / find / reduce)
- 三項演算子 / オプショナルチェーン / Nullish coalescing
- async/await(非同期処理)
- モジュール(import / export)
────────────────────────────────────────
1. 変数宣言 — const と let だけ使え
JSには変数宣言の方法が3つあります。var、let、const です。
ただし、モダンなJSでは var は使いません。理由は後述します。
基本の使い分け
const name = “太郎”; // 再代入しない変数
let count = 0; // 再代入する変数
count = 1; // OK
name = “花子”; // エラー!constは再代入不可
💡 迷ったら const を使うのが現代のベストプラクティスです。後から再代入が必要になったときだけ let に変えればOKです。
なぜ var を使わないのか
var はスコープが「関数スコープ」であるのに対し、const と let は「ブロックスコープ」です。ブロックスコープとは {} で囲まれた範囲のことで、直感に近い挙動をします。
// var の問題点
if (true) {
var x = 10;
}
console.log(x); // 10 が出てしまう(ブロックの外でも生きている)
// let ならブロックの外に出ない
if (true) {
let y = 10;
}
console.log(y); // エラー!(意図通りの挙動)
var はこういった「意図しない挙動」を引き起こしやすいので、新しいコードでは使わないのが定石です。
────────────────────────────────────────
2. テンプレートリテラル — 文字列をスマートに書く
文字列の中に変数を埋め込むとき、昔は + で連結していました。
// 昔のやり方(読みにくい)
const msg = “こんにちは、” + name + “さん。あなたは” + age + “歳です。”;
// テンプレートリテラル(読みやすい)
const msg = `こんにちは、${name}さん。あなたは${age}歳です。`;
バッククォート(`)で囲み、変数は ${} の中に入れるだけです。${} の中にはJSの式なら何でも書けます。
const a = 3;
const b = 5;
console.log(`${a} + ${b} = ${a + b}`); // “3 + 5 = 8”
// 複数行もそのまま書ける
const html = `
<div>
<p>${name}</p>
</div>
`;
────────────────────────────────────────
3. アロー関数 — 関数の書き方を統一する
アロー関数は function キーワードを使わない関数の書き方です。現代のJSコードでは非常によく見かけるため、読み書きできるようにしましょう。
基本の書き方
// 従来の書き方
function add(a, b) {
return a + b;
}
// アロー関数
const add = (a, b) => {
return a + b;
};
// 処理が1行なら return と {} を省略できる
const add = (a, b) => a + b;
// 引数が1つなら () も省略できる
const double = n => n * 2;
// 引数なし
const hello = () => “Hello!”;
function との違い:this の挙動
function とアロー関数には this の扱いに大きな違いがあります。ただし、最初のうちは「コールバック関数(他の関数に渡す関数)にはアロー関数を使う」と覚えておけば大丈夫です。
// コールバックとしてよく使う
setTimeout(() => {
console.log(“1秒後に実行”);
}, 1000);
[1, 2, 3].forEach(n => {
console.log(n);
});
────────────────────────────────────────
4. 分割代入 — オブジェクトや配列を素早く取り出す
オブジェクトや配列の中身を変数に取り出す構文です。覚えると一気にコードがスッキリします。
オブジェクトの分割代入
const user = { name: “花子”, age: 25, city: “東京” };
// 従来の書き方
const name = user.name;
const age = user.age;
// 分割代入
const { name, age } = user;
// 別名をつけることもできる
const { name: userName, age: userAge } = user;
// デフォルト値も設定できる
const { name, role = “guest” } = user;
console.log(role); // “guest”(userにroleがないため)
配列の分割代入
const colors = [“red”, “green”, “blue”];
const [first, second] = colors;
console.log(first); // “red”
// 途中をスキップする
const [, , third] = colors;
console.log(third); // “blue”
関数の引数での分割代入(これが一番よく出る)
// 従来の書き方
const greet = (user) => `${user.name}は${user.age}歳です`;
// 引数の時点で分割代入するとスッキリ
const greet = ({ name, age }) => `${name}は${age}歳です`;
greet({ name: “花子”, age: 25 }); // “花子は25歳です”
💡 Reactなどのフロントエンドフレームワークではこのパターンが頻出します。
────────────────────────────────────────
5. スプレッド構文 / レスト構文
見た目は同じ … ですが、使う場所によって役割が変わります。
スプレッド構文 — 展開する
const a = [1, 2, 3];
const b = [4, 5, 6];
const copy = […a]; // [1, 2, 3](コピー)
const merged = […a, …b]; // [1, 2, 3, 4, 5, 6](結合)
const added = […a, 0]; // [1, 2, 3, 0](要素を追加)
// オブジェクトも同様
const base = { x: 1, y: 2 };
const extended = { …base, z: 3 }; // { x: 1, y: 2, z: 3 }
const updated = { …base, y: 99 }; // { x: 1, y: 99 }(上書き)
💡 配列やオブジェクトを直接変更せずに「新しいものを作る」ときに多用します。Reactの状態管理でも頻繁に登場します。
レスト構文 — 残りをまとめる
// 関数の引数で「残り全部」を受け取る
const sum = (…nums) => nums.reduce((acc, n) => acc + n, 0);
sum(1, 2, 3, 4); // 10
// 分割代入と組み合わせて「残り」を取り出す
const [first, …rest] = [1, 2, 3, 4, 5];
console.log(rest); // [2, 3, 4, 5]
const { name, …others } = { name: “花子”, age: 25, city: “東京” };
console.log(others); // { age: 25, city: “東京” }
────────────────────────────────────────
6. 配列操作 — map / filter / find / reduce
配列を扱うときに必須の高階関数です。for ループより読みやすく、バグも起きにくいです。
map — 変換して新しい配列を作る
const nums = [1, 2, 3, 4, 5];
const doubled = nums.map(n => n * 2);
// [2, 4, 6, 8, 10]
const users = [{ name: “太郎”, age: 20 }, { name: “花子”, age: 25 }];
const names = users.map(user => user.name);
// [“太郎”, “花子”]
filter — 条件を満たすものだけ取り出す
const evens = nums.filter(n => n % 2 === 0);
// [2, 4]
const adults = users.filter(user => user.age >= 20);
// 20歳以上のユーザーだけ
find — 最初の一致要素を1つ返す
const users = [{ id: 1, name: “太郎” }, { id: 2, name: “花子” }];
const user = users.find(u => u.id === 2);
// { id: 2, name: “花子” }
// 見つからない場合は undefined
const notFound = users.find(u => u.id === 99);
// undefined
reduce — 配列を1つの値にまとめる
少し難しいですが、合計や集計処理に使います。
const total = nums.reduce((acc, n) => acc + n, 0);
// 15(初期値0に各要素を足していく)
メソッドチェーン — 組み合わせて使う
これら4つは組み合わせて使えます。
const users = [
{ name: “太郎”, age: 17, active: true },
{ name: “花子”, age: 25, active: true },
{ name: “次郎”, age: 30, active: false },
{ name: “桜”, age: 22, active: true },
];
// アクティブな成人ユーザーの名前一覧
const result = users
.filter(u => u.active && u.age >= 18)
.map(u => u.name);
// [“花子”, “桜”]
────────────────────────────────────────
7. 条件の書き方を短くする3つの構文
三項演算子 — シンプルな if/else の代替
// if/else
let label;
if (isLoggedIn) {
label = “ログアウト”;
} else {
label = “ログイン”;
}
// 三項演算子(1行で書ける)
const label = isLoggedIn ? “ログアウト” : “ログイン”;
💡 入れ子にするのは可読性が下がるので避けましょう。
例: a > 0 ? (a > 10 ? “大きい” : “普通“) : “小さい” ←これはNG
オプショナルチェーン(?.)— nullチェックを省略する
// 従来の書き方
const city = user && user.address && user.address.city;
// オプショナルチェーン
// 途中で null/undefined なら undefined を返す
const city = user?.address?.city;
// メソッドにも使える
const len = str?.length;
const result = arr?.find(n => n > 3);
Nullish coalescing(??)— null/undefined のときだけデフォルト値
// || との違いに注意
const name = inputName || “名無し”;
// 問題:inputName が 0 や false や “” のときもデフォルト値になる
// ?? なら null と undefined のときだけデフォルト値を使う
const name = inputName ?? “名無し”;
const count = userCount ?? 0;
────────────────────────────────────────
8. async/await — 非同期処理をスッキリ書く
APIを叩いたりデータを取得するとき、JavaScriptは「非同期処理」を行います。async/await はその処理を同期処理のように読みやすく書くための構文です。
基本の書き方
// 関数に async をつけると、その中で await が使える
const fetchUser = async (id) => {
const response = await fetch(`https://api.example.com/users/${id}`);
const data = await response.json();
return data;
};
💡 await は「Promiseの処理が終わるまで待つ」という意味です。async 関数の中でしか使えません。
エラーハンドリング — try/catch を使う
const fetchUser = async (id) => {
try {
const response = await fetch(`https://api.example.com/users/${id}`);
if (!response.ok) {
throw new Error(`HTTPエラー: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error(“取得に失敗しました:”, error);
return null;
}
};
複数の非同期処理を並列で実行する
// 順番に実行(遅い)
const user = await fetchUser(1);
const posts = await fetchPosts(1);
// 並列で実行(速い)
const [user, posts] = await Promise.all([
fetchUser(1),
fetchPosts(1),
]);
────────────────────────────────────────
9. import / export — コードをファイルに分ける
規模が大きくなると、コードを複数ファイルに分割して管理します。import / export はその仕組みです。
named export — 複数の値をエクスポートする
// utils.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a – b;
export const PI = 3.14159;
// main.js(使う側)
import { add, PI } from “./utils.js”;
// 別名をつけて import することもできる
import { add as sum } from “./utils.js”;
default export — ファイルの主要な値をエクスポートする
// Button.js
const Button = ({ label, onClick }) => (
<button onClick={onClick}>{label}</button>
);
export default Button;
// App.js(使う側)
import Button from “./Button.js”; // {} なしで import
どちらを使うべきか
named export は1ファイルから複数エクスポートしたいとき(ユーティリティ関数集など)に使います。default export はReactコンポーネントなど「そのファイルの主役」が1つのときに使います。
────────────────────────────────────────
まとめ
以上が「これだけ覚えれば戦える」JS構文の全てです。改めて一覧にすると:
| # | 構文 | 一言まとめ |
| 1 | const / let | var は捨てる。迷ったら const |
| 2 | テンプレートリテラル | バッククォートで文字列をスマートに書く |
| 3 | アロー関数 | () => で関数を短く書く |
| 4 | 分割代入 | オブジェクト・配列をサクッと取り出す |
| 5 | スプレッド / レスト | … で展開したり、まとめたり |
| 6 | map / filter / find / reduce | 配列操作の4本柱 |
| 7 | 三項演算子 / ?. / ?? | 条件を短く書く3兄弟 |
| 8 | async/await | 非同期処理を同期処理っぽく書く |
| 9 | import / export | コードをファイルで分割する |
これらをマスターすれば、ReactやVue、Node.jsのコードも読み書きできるようになります。
一度に全部覚えようとせず、実際にコードを書きながら少しずつ体に馴染ませていくのが一番の近道です。
ぜひ手を動かして試してみてください!

コメント