コメントの書き方
1行のコメントは冒頭に「//」をつけるだけ
// これは1行コメント
複数行のコメントは「/* */」で文字列を囲む
/* これは複数行コメント
2行目のコメント
3行目のコメント */
変数と定数
過去の変数:var
var a = 10;
- 関数スコープ(関数全体で有効)
- ブロックスコープを無視する(
if
やfor
の中で宣言しても外からアクセスできる) - 再宣言・再代入どちらも可能
- デメリット:予期せぬスコープの広がりや変数上書きのリスクが高い
- 使用推奨度: 現代ではほとんど使わない
通常の変数:let
let b = 20;
- ブロックスコープ(
{ ... }
の中だけで有効) - 再代入は可能
- 再宣言は不可
- メリット:予期せぬスコープ汚染を防げる
- 使用推奨度: 基本的に
var
ではなくlet
を使うべき
定数:const
const c = 30;
- ブロックスコープ(
{ ... }
の中だけで有効) - 再代入・再宣言不可
- ただし、オブジェクトや配列の「中身の変更」は可能
const arr = [1, 2];
arr.push(3); // OK
arr = [4, 5]; // エラー
- メリット:値を固定することで意図が明確になり、バグを減らせる
- 使用推奨度: 変数の値を変更しない場合はこちらを使う
var, let, constの使い分け
- 基本は
const
を優先 → 値を変更する必要がない限りこちら - 変更が必要な場合は
let
→ ループカウンタや再代入が必要な変数 var
は使わない → 古いコードの互換性維持以外では不要
データ型の種類
- JavaScriptは、動的型付け言語なので、変数にデータ型を明示する必要はない
- 基本的なデータ型(プリミティブ型)と、オブジェクト型がある
プリミティブ型(基本データ型)
- Number: 数値(整数・小数の区別なし)
- String: 文字列
- Boolean: true または false
- Null: 「存在しない」ことを明示する値。例:
let data = null;
- Undefined: 変数はあるけど中身は空っぽの状態
テンプレートリテラルの使い方(文字列に変数を埋め込む)
- 普通の文字列はシングル
'...'
やダブル"..."
で囲むが、テンプレートリテラルは バッククォート(`
) を使う -
${...}
の中に変数や式を埋め込める
const name = "Taro";
// 通常の文字列
console.log("Hello, " + name + "!");
// テンプレートリテラル
console.log(`Hello, ${name}!`);
通常の文字列は \n
を使わないと改行できないが、テンプレートリテラルはそのまま改行を書ける
const msg = `これは1行目
これは2行目
これは3行目`;
console.log(msg);
変数だけでなく、計算式や関数の結果も書ける
const a = 5;
const b = 3;
console.log(`${a} + ${b} = ${a + b}`); // "5 + 3 = 8"
オブジェクト型
プリミティブ以外はすべて「オブジェクト」
- Object(基本的な連想配列的な入れ物)
let person = {name: "Taro", age: 20};
- Array(配列)
let nums = [1, 2, 3];
- Function(関数もオブジェクトの一種)
function greet() { return "Hello"; }
- Date(日付オブジェクト)
let today = new Date();
- RegExp(正規表現)
let pattern = /abc/;
- その他: Map, Set, WeakMap, WeakSet なども利用可能。
演算子の種類
算術演算子
数値の計算に使用
let a = 10, b = 3;
a + b // 13(加算)
a - b // 7(減算)
a * b // 30(乗算)
a / b // 3.333...(除算)
a % b // 1(剰余:割った余り)
a ** b // 1000(累乗:10の3乗)
「+」は文字列の結合も可能(ただしテンプレートリテラル `${a}と${b}`
の方が楽)
"Hello" + " World" // "Hello World"
代入演算子
変数に値を代入、または演算と代入を同時に行う
let x = 5;
x += 3; // x = x + 3 → 8
x -= 2; // x = x - 2 → 6
x *= 4; // x = x * 4 → 24
x /= 3; // x = x / 3 → 8
x %= 5; // x = x % 5 → 3
x **= 2; // x = x ** 2 → 9
比較演算子
値を比較し、真偽値(true/false)を返す
5 == "5" // true(値が等しい:型は無視)
5 === "5" // false(厳密に等しい:型もチェック)
5 != "5" // false(等しくない:型無視)
5 !== "5" // true(厳密に等しくない)
5 > 3 // true
5 < 3 // false
5 >= 5 // true
5 <= 4 // false
論理演算子
条件式を組み合わせる
true && false // false(論理積 AND)
true || false // true(論理和 OR)
!true // false(否定 NOT)
インクリメント・デクリメント
1の加算/減算を簡潔に表現。
let n = 5;
n++; // 6(後置インクリメント)
++n; // 7(前置インクリメント)
n--; // 6(後置デクリメント)
--n; // 5(前置デクリメント)
ビット演算子
2進数レベルでの演算に使用
5 & 3 // 1 (AND)
5 | 3 // 7 (OR)
5 ^ 3 // 6 (XOR)
~5 // -6 (NOT)
5 << 1 // 10(左シフト)
5 >> 1 // 2 (右シフト)
その他の演算子
typeof
→ 型を調べるA instanceof B
→ AはBというクラスか?を確認A in B
→ AというプロパティがBに存在するか?を確認delete
→ オブジェクトのプロパティ削除
typeof "abc"; // "string"
[1, 2, 3] instanceof Array; // true
"length" in [1,2,3]; // 配列には自動的に length プロパティ(要素数を表す)が存在するためtrue
let obj = {a:1};
delete obj.a; // obj = {}
条件分岐
if文の書き方
最も基本的な条件分岐
let score = 80;
if (score >= 90) {
console.log("A");
} else if (score >= 70) {
console.log("B");
} else {
console.log("C");
}
if
→ 条件がtrueのとき実行else if
→ 別の条件を続けて判定else
→ どの条件も当てはまらなかったとき
switch文の書き方
特定の値に応じて分岐するときに使いやすい
let fruit = "apple";
switch (fruit) {
case "apple":
console.log("りんご");
break;
case "banana":
console.log("バナナ");
break;
case "orange":
console.log("オレンジ");
break;
default:
console.log("その他の果物");
}
case
に一致したところから実行される。break
を書かないと、次のcase
まで処理が続いてしまう(フォールスルー)。default
はどのcase
にも当てはまらなかった場合の処理。
三項演算子
1行で書ける条件分岐:「(条件式) ? trueの場合 : falseの場合」と書く
let age = 20;
let status = (age >= 18) ? "成人" : "未成年";
console.log(status); // 成人
例外処理の書き方
エラーが起きそうな処理を try
に入れ、エラー発生時の処理を catch
で受け止める
try {
// エラーが起きるかもしれない処理
let result = 10 / 0;
console.log(result);
throw new Error("手動でエラーを発生させた"); // エラーを投げる例
} catch (e) {
// エラー時の処理
console.log("エラーが発生しました: " + e.message);
} finally {
// 成否に関わらず必ず実行される処理(省略可)
console.log("処理終了");
}
try
:通常処理を書く部分。エラーが起きると、以降はスキップされてcatch
に飛ぶcatch (e)
:エラーオブジェクトがe
に渡されるので、e.message
でメッセージを確認可能finally
:成功しても失敗しても最後に必ず実行される部分。リソース解放や後処理に便利
繰り返し処理
for文の書き方
繰り返し処理の基本形
for (let i = 0; i < 5; i++) {
console.log(i); // 0,1,2,3,4
}
while文の書き方
条件が true の間、繰り返す
let n = 0;
while (n < 5) {
console.log(n);
n++;
}
do...while 文
一度は必ず処理を実行し、その後条件を判定
let m = 0;
do {
console.log(m);
m++;
} while (m < 5);
for...in 文
オブジェクトの プロパティ名 を列挙する
let person = {name: "Taro", age: 20};
for (let key in person) {
console.log(key, person[key]);
}
// name Taro
// age 20
for...of 文
配列や文字列などの 値 を順番に取り出す
let arr = [10, 20, 30];
for (let value of arr) {
console.log(value);
}
// 10
// 20
// 30
配列のメソッドによる繰り返し
モダンJavaScriptでは配列メソッドを使うことも多い
[1, 2, 3].forEach(num => console.log(num));
ループを中断したりスキップする方法
break
は、ループ全体を即座に抜ける
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // i が 5 の時点でループ終了
}
console.log(i);
}
// 出力: 0,1,2,3,4
continue
は、処理をスキップして次のループに進む
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 偶数はスキップ
}
console.log(i);
}
// 出力: 1,3,5,7,9
入れ子のループで外側のループを制御したいときに ラベル を付けて制御できる
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
break outer; // (1, 1)だったら外側のループごと抜ける
}
console.log(i, j);
}
}
// 出力: (0,0), (0,1), (0,2), (1,0)
同様に continue outer;
とすれば外側の次のループにスキップします。
関数を自作する方法
関数の基本構文
関数宣言(Function Declaration)
function add(a, b) {
return a + b;
}
add(2, 3); // 5
- 巻き上げ(hoisting) されるため、定義より前でも呼び出せる
- 可読性が高く、ユーティリティ関数に向く
関数式(Function Expression)
const add = function(a, b) {
return a + b;
};
add(2, 3); // 5
- 変数に代入する形
- 代入前は使えない(宣言タイミングが実行時)
オプション構文(共通)
function greet(name = "Guest") { // デフォルト引数
return `Hello, ${name}`;
}
function sum(...nums) { // 可変長引数(rest)
return nums.reduce((a, b) => a + b, 0);
}
function* counter() { // ジェネレーター(必要に応じて)
let i = 0;
while (true) yield i++;
}
引数の参照渡しと値渡し
プリミティブ型は「値渡し」
「値渡し」=関数の中で引数を変更しても、元の値には影響しない
function changeValue(x) {
x = 100; // ローカル変数xが変わるだけ
}
let a = 10;
changeValue(a);
console.log(a); // 10(元のaは変わらない)
オブジェクト型は「参照が値渡し」
配列・オブジェクト・関数など オブジェクト型 は「参照(アドレス)」がコピーされる
このため、関数の中で 参照先の中身を変更すると元の変数にも影響 する
function addItem(arr) {
arr.push(4); // 参照先の配列に直接操作
}
let nums = [1,2,3];
addItem(nums);
console.log(nums); // [1,2,3,4] (元の配列が変更された)
関数内で参照変数を別のオブジェクトに代入しても、呼び出し元には影響しない
function replaceArray(arr) {
arr = [9,9,9]; // 参照を新しい配列に置き換え
}
let nums = [1,2,3];
replaceArray(nums);
console.log(nums); // [1,2,3] (元の参照はそのまま)
元のオブジェクトを壊したくないときはコピーして渡す
let arrCopy = [...arr]; // スプレッド構文で浅いコピー
let objCopy = {...obj}; // オブジェクトの浅いコピー
アロー関数(ラムダ)
const add = (a, b) => a + b; // 1行は暗黙のreturn
ブロックと明示的return
const add = (a, b) => {
const r = a + b;
return r;
};
オブジェクトリテラルを返す
const makeUser = (name) => ({ name, active: true });
引数1つは丸カッコ不要・引数なしは丸カッコだけ
const square = x => x * x;
const getTime = () => Date.now();
重要な違い(従来のfunctionとの比較)
this
・arguments
を束縛しない(外側のthis
をそのまま使う=レキシカルthis)new
でコンストラクト不可(クラスやコンストラクタ用途には不向き)prototype
を持たない
this
の例
const obj = {
x: 42,
f1: function() { return this.x; }, // 42(objがthis)
f2: () => this.x // undefined相当(外側のthisに依存)
};
組み込みオブジェクト
オブジェクトの基本
オブジェクトは {キー: 値}
のペアで表される
let person = { name: "Taro", age: 20 };
プロパティアクセス
person.name; // "Taro"
person["age"]; // 20
キーや値の列挙
Object.keys(obj)
→ プロパティ名の配列Object.values(obj)
→ 値の配列Object.entries(obj)
→ [キー, 値] の配列
Object.keys(person); // ["name","age"]
Object.values(person); // ["Taro",20]
Object.entries(person); // [["name","Taro"],["age",20]]
JSONとの相互変換
JSON.stringify(obj)
→ JSON文字列に変換JSON.parse(string)
→ JSON文字列をオブジェクトに変換
JSON.stringify({a:1, b:2}); // '{"a":1,"b":2}'
JSON.parse('{"a":1,"b":2}'); // {a:1, b:2}
文字列:Stringオブジェクト
- 文字列は プリミティブ型の
String
だが、メソッド呼び出し時には自動的にString
オブジェクトに変換される - 文字列操作は イミュータブル(不変) で、元の文字列は変更されず新しい文字列を返す
文字数・部分文字列
str.length
→ 文字数を返すstr.charAt(index)
→ 指定位置の文字を返すstr.charCodeAt(index)
→ 指定位置の文字コード(UTF-16)を返すstr.at(index)
(ES2022) → 負のインデックスも可能
"Hello".length; // 5
"Hello".charAt(1); // "e"
"A".charCodeAt(0); // 65
"Hello".at(-1); // "o"
部分文字列の取得
tr.slice(start, end)
→ 指定範囲を切り出すstr.substring(start, end)
→ sliceに似るが負数を0扱いstr.substr(start, length)
(非推奨) → 指定位置から長さ分
"Hello".slice(1, 4); // "ell"
"Hello".substring(1, 4); // "ell"
"Hello".substr(1, 3); // "ell"
検索
str.indexOf(search, fromIndex)
→ 先頭から検索str.lastIndexOf(search)
→ 末尾から検索str.includes(search)
→ 部分文字列を含むかstr.startsWith(search)
→ 指定文字で始まるかstr.endsWith(search)
→ 指定文字で終わるか
"Hello".indexOf("l"); // 2
"Hello".lastIndexOf("l"); // 3
"Hello".includes("ell"); // true
"Hello".startsWith("He"); // true
"Hello".endsWith("lo"); // true
変換
str.toUpperCase()
/str.toLowerCase()
str.trim()
→ 前後の空白を削除str.trimStart()
/str.trimEnd()
"Hello".toUpperCase(); // "HELLO"
" Hello ".trim(); // "Hello"
" Hello".trimStart(); // "Hello"
置換・分割
str.replace(search, newStr)
→ 最初の一致を置換str.replaceAll(search, newStr)
(ES2021) → すべて置換str.split(separator)
→ 区切り文字で分割(配列を返す)
"apple".replace("p", "P"); // "aPple"
"apple".replaceAll("p", "P"); // "aPPle"
"a,b,c".split(","); // ["a", "b", "c"]
繰り返し・結合
str.concat(str2, str3, ...)
→ 文字列を結合str.repeat(count)
→ 文字列を繰り返す
"Hello".concat(" ", "World"); // "Hello World"
"Hi".repeat(3); // "HiHiHi"
その他便利なもの
String.fromCharCode(num1, num2, ...)
→ 文字コードから文字を作成str.match(regexp)
→ 正規表現でマッチした部分を返すstr.search(regexp)
→ 正規表現で一致したインデックスを返す
数値計算:Mathオブジェクト
丸め・絶対値
Math.round(x)
→ 四捨五入Math.floor(x)
→ 小数点以下切り捨てMath.ceil(x)
→ 小数点以下切り上げMath.trunc(x)
→ 小数点以下切り捨て(符号を維持)Math.abs(x)
→ 絶対値
最大・最小
Math.max(a, b, c...)
→ 最大値Math.min(a, b, c...)
→ 最小値
乱数
Math.random()
→ 0以上1未満のランダムな小数
冪乗・平方根
Math.pow(x, y)
→ xのy乗(x ** y
と同じ)Math.sqrt(x)
→ 平方根
配列:Arrayオブジェクト
配列の作成・長さの取得
let arr = [1, 2, 3];
let arr2 = new Array(5); // 要素数5の空配列
arr.length; // 3
要素の追加・削除
push()
/pop()
→ 末尾に追加/末尾から削除unshift()
/shift()
→ 先頭に追加/先頭から削除splice(start, deleteCount, ...items)
→ 要素の削除・挿入
let arr = [1,2];
arr.push(3); // [1,2,3]
arr.pop(); // [1,2]
arr.unshift(0); // [0,1,2]
arr.shift(); // [1,2]
let arr = [1,2,3,4];
arr.splice(1,2,"a","b"); // [1,"a","b",4]
走査(ループ処理)
forEach(callback)
→ 各要素に対して処理を実行map(callback)
→ 各要素を変換し、新しい配列を返すfilter(callback)
→ 条件がtrueの要素だけ返すreduce(callback, initial)
→ 累積処理(合計・集約など)some(callback)
→ 条件を満たす要素が1つでもあれば trueevery(callback)
→ 全要素が条件を満たせば true
[1,2,3].forEach(x => console.log(x));
[1,2,3].map(x => x*2); // [2,4,6]
[1,2,3,4].filter(x => x%2===0); // [2,4]
[1,2,3,4].reduce((sum, x) => sum+x, 0); // 10
[1,2,3].some(x => x > 2); // true
[1,2,3].every(x => x > 0); // true
検索・判定
includes(value)
→ 要素が含まれるかindexOf(value)
/lastIndexOf(value)
→ インデックスを返すfind(callback)
→ 条件を満たす最初の要素findIndex(callback)
→ 条件を満たす最初のインデックス
[1,2,3].includes(2); // true
[1,2,3,2].indexOf(2); // 1
[1,2,3,2].lastIndexOf(2); // 3
[1,2,3].find(x => x > 1); // 2
[1,2,3].findIndex(x => x > 1); // 1
並び替え・変換
sort(compareFn)
→ 並べ替えreverse()
→ 逆順join(separator)
→ 配列を文字列に変換toString()
→ 文字列化
[3,1,2].sort(); // [1,2,3](文字列順)
[3,1,2].sort((a,b)=>a-b); // [1,2,3](数値順)
[1,2,3].reverse(); // [3,2,1]
["a","b","c"].join("-"); // "a-b-c"
[1,2,3].toString(); // "1,2,3"
新しい配列を作る
concat()
→ 配列を結合slice(start, end)
→ 部分配列を取得(元は変更しない)flat(depth)
→ ネストを平坦化flatMap(callback)
→ map + flat(深さ1)
[1,2].concat([3,4]); // [1,2,3,4]
[1,2,3,4].slice(1,3); // [2,3]
[1,[2,[3]]].flat(2); // [1,2,3]
[1,2,3].flatMap(x => [x, x*2]); // [1,2,2,4,3,6]
日付:Dateオブジェクト
Dateオブジェクトの生成
- 現在日時
- 指定日時
- UNIX時間(1970-01-01からのミリ秒)
let now = new Date();
new Date("2025-09-03T10:00:00"); // 文字列から
new Date(2025, 8, 3, 10, 0, 0); // 年,月(0始まり),日,時,分,秒
// → 2025年9月3日 10:00:00
new Date(0); // 1970-01-01T00:00:00.000Z
Date.now(); // 例: 1756896000000
日付・時刻の取得(getter)
getFullYear()
→ 年(西暦)getMonth()
→ 月(0始まり: 0=1月, 11=12月)getDate()
→ 日(1〜31)getDay()
→ 曜日(0=日曜, 6=土曜)getHours()
/getMinutes()
/getSeconds()
/getMilliseconds()
getTime()
→ UNIX時間(1970-01-01からのミリ秒)
UTC基準で取得する場合は getUTCFullYear()
, getUTCHours()
などを使う
日付・時刻の設定(setter)
let d = new Date();
d.setFullYear(2030);
d.setMonth(0); // 月は0始まりなので、これで1月
d.setDate(15); // 15日
d.setHours(8); // 8時
d.setMinutes(30); // 30分
文字列変換
toString()
→ ローカル形式の文字列toDateString()
→ 日付だけtoTimeString()
→ 時刻だけtoISOString()
→ ISO形式(YYYY-MM-DDTHH:mm:ss.sssZ
)toLocaleString()
→ ロケールに応じた文字列
new Date().toLocaleString("ja-JP"); // "2025/9/3 12:34:56"
日付計算
Date
は内部的にミリ秒で管理されているため、足し算・引き算で計算可能
let d = new Date();
d.setDate(d.getDate() + 7); // 7日後
let d1 = new Date("2025-09-01");
let d2 = new Date("2025-09-03");
let diff = d2 - d1; // ミリ秒差
let days = diff / (1000 * 60 * 60 * 24); // 日数差