目的別のJavaScript構文・メソッド早見表
📌 変数と定数
値やオブジェクトを格納するための名前付きの入れ物を宣言します。
キーワード | スコープ | 再宣言 | 再代入 | 主な用途・注意点 |
---|---|---|---|---|
var |
関数スコープ or グローバルスコープ | 可能 | 可能 | 古い書き方。巻き上げ (hoisting) が発生し、意図しない動作の原因になることがあるため、現在は let や const の使用が推奨されます。 |
let |
ブロックスコープ {} |
不可 (同一スコープ内) | 可能 | 再代入が必要な変数を宣言する場合に使用します。✨ |
const |
ブロックスコープ {} |
不可 (同一スコープ内) | 不可 | 再代入が不要な定数(特にオブジェクトや配列)を宣言する場合に使用します。初期化が必須です。オブジェクトや配列の中身は変更可能です。🌟 |
コード例
// var (非推奨)
var message = "Hello";
var message = "Hi"; // 再宣言可能
message = "Hey"; // 再代入可能
console.log(message); // 出力: Hey
// let
let count = 0;
// let count = 1; // エラー:同一スコープ内で再宣言不可
count = 5; // 再代入可能
console.log(count); // 出力: 5
if (true) {
let count = 10; // ブロックスコープなので別の変数
console.log(count); // 出力: 10
}
console.log(count); // 出力: 5
// const
const PI = 3.14;
// const PI = 3; // エラー: 再宣言不可
// PI = 3.1415; // エラー: 再代入不可
console.log(PI); // 出力: 3.14
const user = { name: "Alice", age: 30 };
// user = { name: "Bob", age: 25 }; // エラー: 再代入不可
user.age = 31; // オブジェクトのプロパティは変更可能
console.log(user); // 出力: { name: 'Alice', age: 31 }
const colors = ["red", "green"];
// colors = ["blue", "yellow"]; // エラー: 再代入不可
colors.push("blue"); // 配列の要素は変更可能
console.log(colors); // 出力: ['red', 'green', 'blue']
💾 データ型
JavaScriptが扱うデータの種類です。プリミティブ型とオブジェクト型に大別されます。
プリミティブ型 (Primitive Types)
- String: 文字列 (“Hello”, ‘World’, `Template`)
- Number: 数値 (10, 3.14, NaN, Infinity)
- BigInt: 任意精度の整数 (
123n
) –Number.MAX_SAFE_INTEGER
を超える整数を扱う - Boolean: 真偽値 (
true
,false
) - Undefined: 未定義値 (変数が宣言されたが値が代入されていない状態)
- Null: 値が存在しないことを意図的に示す値
- Symbol: 一意で不変な値 (
Symbol('description')
) – オブジェクトプロパティのキーなどに使用
オブジェクト型 (Object Type)
- Object: キーと値のペアのコレクション (
{ key: 'value' }
) - Array: 順序付けられた値のリスト (
[1, 2, 3]
) - Function: 実行可能なコードのブロック
- Date: 日付と時刻
- RegExp: 正規表現
- その他 (Map, Set, WeakMap, WeakSet など)
typeof 演算子
値のデータ型を文字列で返します。ただし、null
は "object"
を返すなど、注意点があります。
console.log(typeof "hello"); // "string"
console.log(typeof 123); // "number"
console.log(typeof 123n); // "bigint"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol("id")); // "symbol"
console.log(typeof null); // "object" (歴史的な理由による仕様)
console.log(typeof { a: 1 }); // "object"
console.log(typeof [1, 2]); // "object" (配列もオブジェクトの一種)
console.log(typeof function(){});// "function" (オブジェクトだが typeof では "function")
console.log(typeof new Date()); // "object"
console.log(typeof /abc/); // "object" (環境によっては "function" の場合も)
// 配列かどうかを正確に判定するには Array.isArray() を使う
console.log(Array.isArray([1, 2])); // true
console.log(Array.isArray({ a: 1 })); // false
🧮 演算子
値に対して操作を行う記号です。
種類 | 演算子 | 例 | 説明 |
---|---|---|---|
算術演算子 | + |
x + y |
加算 (文字列連結にも使用) |
- |
x - y |
減算 | |
* |
x * y |
乗算 | |
/ |
x / y |
除算 | |
% |
x % y |
剰余 (余り) | |
** |
x ** y |
べき乗 (ES2016) | |
代入演算子 | = |
x = y |
代入 |
+= |
x += y |
x = x + y と等価 |
|
-= |
x -= y |
x = x - y と等価 |
|
*= , /= , %= , **= |
x *= y |
他の算術演算子との組み合わせ | |
&&= , ||= |
x &&= y |
論理AND/OR代入 (ES2021) | |
??= |
x ??= y |
Null合体代入 (ES2021) | |
比較演算子 | == |
x == y |
等価 (型変換を行う) 🤔 |
!= |
x != y |
不等価 (型変換を行う) | |
=== |
x === y |
厳密等価 (型変換を行わない) 👍 | |
!== |
x !== y |
厳密不等価 (型変換を行わない) 👍 | |
> |
x > y |
より大きい | |
< |
x < y |
より小さい | |
>= |
x >= y |
以上 | |
<= |
x <= y |
以下 | |
論理演算子 | && |
x && y |
論理AND (かつ) |
|| |
x || y |
論理OR (または) | |
! |
!x |
論理NOT (否定) | |
Null合体演算子 | ?? |
x ?? y |
左辺が null または undefined の場合に右辺を返す (ES2020) |
三項演算子 | ? : |
condition ? value1 : value2 |
条件が true なら value1、false なら value2 を返す |
その他の演算子 | typeof |
typeof x |
オペランドの型を文字列で返す |
instanceof |
obj instanceof Constructor |
オブジェクトが特定のコンストラクタのインスタンスか判定する |
⚙️ 制御構文
プログラムの実行フローを制御します。
条件分岐
const score = 75;
if (score >= 80) {
console.log("優 👍");
} else if (score >= 60) {
console.log("良 😊");
} else {
console.log("可 🤔");
}
ループ (繰り返し処理)
構文 | 用途 | コード例 |
---|---|---|
for |
指定回数の繰り返し、配列のインデックスを使った処理 |
|
for...in |
オブジェクトのプロパティ名を列挙 (順序は保証されない) 🤔 配列には非推奨 (プロトタイプチェーン上のプロパティも列挙する可能性あり) |
|
for...of |
イテラブルオブジェクト (配列, String, Map, Setなど) の要素を順次処理 (ES6) ✨ |
|
while |
条件が true の間、繰り返し (最初に条件判定) |
|
do...while |
条件が true の間、繰り返し (最後に条件判定、最低1回は実行される) |
|
ループ制御
break
: 現在のループ (for
,while
,do...while
,switch
) を終了します。continue
: 現在のループの残りの処理をスキップし、次のイテレーションに進みます (for
,while
,do...while
で使用)。
for (let i = 0; i < 10; i++) {
if (i === 3) {
continue; // iが3の場合はスキップ
}
if (i === 7) {
break; // iが7になったらループ終了
}
console.log(i); // 0, 1, 2, 4, 5, 6 が出力される
}
🔧 関数 (Function)
特定の処理をまとめたブロックで、再利用可能です。
関数の定義方法
種類 | コード例 | 特徴 |
---|---|---|
関数宣言 (Function Declaration) |
|
巻き上げ (hoisting) される。定義前に呼び出し可能。 |
関数式 (Function Expression) |
|
巻き上げされない(変数宣言はされるが、代入は実行時)。無名関数として定義されることが多い。 |
アロー関数 (Arrow Function) (ES6) |
|
構文が短い ✨。this の挙動が異なる(自身の this を持たず、外側のスコープの this を継承)。arguments オブジェクトを持たない。new で呼び出せない。 |
即時実行関数 (IIFE) |
|
定義と同時に実行される。グローバルスコープを汚染しないように変数スコープを作成する目的で使われる。 |
引数と戻り値
- 引数 (Arguments): 関数に渡される値。
- デフォルト引数 (Default Parameters, ES6): 引数が渡されなかった場合のデフォルト値を設定可能。
function greet(name = "Guest") { console.log(`Hello, ${name}!`); } greet(); // "Hello, Guest!" greet("Alice"); // "Hello, Alice!"
- Rest Parameters (ES6): 不定数の引数を配列として受け取る (
...args
)。function sum(...numbers) { return numbers.reduce((total, num) => total + num, 0); } console.log(sum(1, 2, 3)); // 6 console.log(sum(10, 20)); // 30
arguments
オブジェクト: (アロー関数以外) 関数に渡された引数をすべて保持する配列風オブジェクト (非推奨、Rest Parameters推奨)。function logArgs() { console.log(arguments); // Arguments(2) [ 'a', 1, callee: ƒ, Symbol(Symbol.iterator): ƒ ] console.log(arguments.length); // 2 console.log(arguments[0]); // 'a' } logArgs('a', 1);
- デフォルト引数 (Default Parameters, ES6): 引数が渡されなかった場合のデフォルト値を設定可能。
- 戻り値 (Return Value): 関数が処理結果として返す値。
return
文で指定する。return
がない場合やreturn;
の場合はundefined
を返す。
🧩 オブジェクト (Object)
キー (文字列またはSymbol) と値のペアを格納するコレクションです。
オブジェクトの作成とアクセス
// オブジェクトリテラルによる作成
const person = {
name: "Bob",
age: 28,
"is Student": false, // キーにスペースが含まれる場合は引用符で囲む
greet: function() { // メソッド (オブジェクト内の関数)
console.log(`Hi, I'm ${this.name}`);
},
// ES6 メソッド短縮記法
sayBye() {
console.log("Bye!");
}
};
// プロパティへのアクセス
console.log(person.name); // ドット記法: "Bob"
console.log(person["age"]); // ブラケット記法: 28
console.log(person["is Student"]); // キーが特殊な場合はブラケット記法必須
// メソッドの呼び出し
person.greet(); // "Hi, I'm Bob"
person.sayBye(); // "Bye!"
// プロパティの追加・更新
person.city = "Tokyo";
person.age = 29;
console.log(person); // { name: 'Bob', age: 29, ..., city: 'Tokyo' }
// プロパティの削除
delete person["is Student"];
console.log(person["is Student"]); // undefined
this キーワード
this
が参照する値は、関数の呼び出し方によって決まります。
- メソッド呼び出し:
object.method()
の場合、this
はobject
を参照します。 - 通常の関数呼び出し:
func()
の場合、厳格モード (strict mode) ではundefined
、そうでなければグローバルオブジェクト (ブラウザではwindow
) を参照します。 - コンストラクタ呼び出し:
new Constructor()
の場合、this
は新しく生成されるインスタンスを参照します。 - アロー関数: 自身の
this
を持たず、外側のレキシカルスコープのthis
を参照します。 call()
,apply()
,bind()
:this
の値を明示的に指定できます。
便利なObjectメソッド
メソッド | 説明 | コード例 |
---|---|---|
Object.keys(obj) |
オブジェクト自身の列挙可能なプロパティ名の配列を返す。 |
|
Object.values(obj) |
オブジェクト自身の列挙可能なプロパティ値の配列を返す (ES2017)。 |
|
Object.entries(obj) |
オブジェクト自身の列挙可能な [キー, 値] ペアの配列を返す (ES2017)。 |
|
Object.assign(target, ...sources) |
1つ以上のソースオブジェクトから、ターゲットオブジェクトにプロパティをコピーする。ターゲットオブジェクト自体を変更し、それを返す。 |
|
Object.create(proto, [propertiesObject]) |
指定されたプロトタイプオブジェクトを持つ新しいオブジェクトを作成する。 |
|
Object.hasOwnProperty(prop) |
オブジェクト自身が指定されたプロパティを持つかどうかを返す (プロトタイプチェーンは検索しない)。インスタンスメソッド (obj.hasOwnProperty(prop) ) として使うのが一般的。 |
|
📊 配列 (Array)
順序付けられた値のリストです。インデックス (0から始まる整数) を使って要素にアクセスします。
配列の作成とアクセス
// 配列リテラルによる作成
const fruits = ["apple", "banana", "orange"];
const mixed = [1, "two", true, null, { id: 3 }];
const empty = [];
// 要素へのアクセス (インデックスは0から)
console.log(fruits[0]); // "apple"
console.log(fruits[1]); // "banana"
console.log(mixed[4].id); // 3
// 要素の更新
fruits[1] = "grape";
console.log(fruits); // ["apple", "grape", "orange"]
// 配列の長さ (要素数)
console.log(fruits.length); // 3
主要な配列メソッド 🚀
メソッド | 説明 | 元の配列を変更するか | 戻り値 | コード例 |
---|---|---|---|---|
push(item1, ...) |
末尾に要素を追加 | ✅ はい | 新しい長さ |
|
pop() |
末尾の要素を削除して返す | ✅ はい | 削除された要素 |
|
unshift(item1, ...) |
先頭に要素を追加 | ✅ はい | 新しい長さ |
|
shift() |
先頭の要素を削除して返す | ✅ はい | 削除された要素 |
|
splice(start, deleteCount, item1, ...) |
指定位置から要素を削除・追加・置換 | ✅ はい | 削除された要素の配列 |
|
slice(start, end) |
指定範囲の要素を新しい配列として抽出 (endは含まない) | ❌ いいえ | 抽出された要素の新しい配列 |
|
concat(arr1, ...) |
現在の配列に他の配列や値を連結した新しい配列を返す | ❌ いいえ | 連結された新しい配列 |
|
indexOf(item, fromIndex) |
指定要素が最初に現れるインデックスを返す (見つからない場合は -1) | ❌ いいえ | インデックス or -1 |
|
lastIndexOf(item, fromIndex) |
指定要素が最後に現れるインデックスを返す (後方から検索) | ❌ いいえ | インデックス or -1 |
|
includes(item, fromIndex) |
指定要素が含まれているかを真偽値で返す (ES2016) ✨ | ❌ いいえ | Boolean |
|
find(callback) |
条件を満たす最初の要素を返す (見つからない場合は undefined) | ❌ いいえ | 要素 or undefined |
|
findIndex(callback) |
条件を満たす最初の要素のインデックスを返す (見つからない場合は -1) | ❌ いいえ | インデックス or -1 |
|
forEach(callback(currentValue, index, array)) |
各要素に対してコールバック関数を実行 (戻り値なし) | ❌ いいえ | undefined |
|
map(callback(currentValue, index, array)) |
各要素をコールバック関数で処理し、その結果からなる新しい配列を返す | ❌ いいえ | 新しい配列 |
|
filter(callback(element, index, array)) |
コールバック関数が true を返した要素のみからなる新しい配列を返す | ❌ いいえ | 新しい配列 |
|
reduce(callback(accumulator, currentValue, currentIndex, array), initialValue) |
配列の要素を左から右へ、累積的に処理し、単一の値を返す | ❌ いいえ | 累積結果 |
|
reduceRight(...) |
reduce と同様だが、右から左へ処理する |
❌ いいえ | 累積結果 |
|
some(callback) |
いずれかの要素がコールバック関数の条件を満たせば true を返す | ❌ いいえ | Boolean |
|
every(callback) |
すべての要素がコールバック関数の条件を満たせば true を返す | ❌ いいえ | Boolean |
|
join(separator) |
配列の全要素を連結した文字列を返す (区切り文字を指定可能) | ❌ いいえ | 文字列 |
|
sort(compareFunction) |
配列の要素をソートする (デフォルトは文字列としてソート) | ✅ はい | ソートされた配列への参照 |
|
reverse() |
配列の要素の順序を反転させる | ✅ はい | 反転された配列への参照 |
|
Array.isArray(obj) |
オブジェクトが配列かどうかを判定する (静的メソッド) | – | Boolean |
|
Array.from(iterableOrArrayLike) |
イテラブルオブジェクトや配列風オブジェクトから新しい配列を生成する (静的メソッド) | – | 新しい配列 |
|
Array.of(item1, ...) |
引数から新しい配列を生成する (静的メソッド) | – | 新しい配列 |
|
🏛️ クラス (Class) (ES6)
オブジェクト指向プログラミングのための構文糖衣 (シンタックスシュガー) です。プロトタイプベースの継承をより分かりやすく扱えます。
クラス定義とインスタンス化
class Animal {
// コンストラクタ: インスタンス生成時に呼ばれる初期化メソッド
constructor(name) {
this.name = name; // インスタンスプロパティ
}
// メソッド
speak() {
console.log(`${this.name} makes a noise.`);
}
// 静的メソッド: クラス自体に属し、インスタンスからは呼び出せない
static info() {
console.log("This is an Animal class.");
}
// ゲッター: プロパティのようにアクセスできるメソッド
get upperName() {
return this.name.toUpperCase();
}
// セッター: プロパティのように代入できるメソッド
set nickname(value) {
console.log(`Setting nickname for ${this.name} to ${value}`);
this._nickname = value; // 通常、内部プロパティには _ を付ける慣習
}
get nickname() {
return this._nickname;
}
}
// インスタンスの生成
const animal = new Animal("Generic Animal");
animal.speak(); // "Generic Animal makes a noise."
console.log(animal.upperName); // "GENERIC ANIMAL" (ゲッター呼び出し)
animal.nickname = "Gen"; // (セッター呼び出し)
console.log(animal.nickname); // "Gen" (ゲッター呼び出し)
// 静的メソッドの呼び出し
Animal.info(); // "This is an Animal class."
// animal.info(); // エラー: animal.info is not a function
継承 (Inheritance)
extends
キーワードで他のクラスを継承し、super
キーワードで親クラスのコンストラクタやメソッドを呼び出せます。
class Dog extends Animal { // Animal クラスを継承
constructor(name, breed) {
// 親クラスのコンストラクタを呼び出す (必須)
super(name);
this.breed = breed;
}
// 親クラスのメソッドをオーバーライド (上書き)
speak() {
console.log(`${this.name} barks.`);
}
// 親クラスのメソッドを呼び出す
parentSpeak() {
super.speak(); // 親クラス (Animal) の speak メソッドを呼び出す
}
wagTail() {
console.log(`${this.name} wags tail.`);
}
}
const dog = new Dog("Buddy", "Golden Retriever");
dog.speak(); // "Buddy barks." (オーバーライドされたメソッド)
dog.parentSpeak(); // "Buddy makes a noise." (親クラスのメソッド呼び出し)
dog.wagTail(); // "Buddy wags tail."
console.log(dog.name); // "Buddy" (親クラスから継承したプロパティ)
console.log(dog.breed); // "Golden Retriever"
⏳ 非同期処理
時間のかかる処理 (ネットワークリクエスト、ファイル読み込みなど) を、他の処理をブロックせずに行うための仕組みです。
コールバック関数 (Callback Function)
非同期処理が完了した後に実行される関数。処理がネストするとコールバック地獄 (Callback Hell) になりやすい 🤔。
function fetchData(url, callback) {
console.log(`Fetching data from ${url}...`);
// 非同期処理をシミュレート
setTimeout(() => {
const data = { result: `Data from ${url}` };
callback(null, data); // 成功時は error に null、data に結果を渡す
// エラーの場合: callback(new Error("Fetch failed!"), null);
}, 1000);
}
fetchData("example.com/data1", (error1, data1) => {
if (error1) {
console.error("Error 1:", error1.message);
return;
}
console.log("Data 1:", data1);
// data1 を使って次の処理
fetchData("example.com/data2", (error2, data2) => {
if (error2) {
console.error("Error 2:", error2.message);
return;
}
console.log("Data 2:", data2);
// さらにネスト...
});
});
Promise (ES6)
非同期処理の最終的な結果 (成功または失敗) を表現するオブジェクト。.then()
で成功時、.catch()
で失敗時の処理を繋げられる。コールバック地獄を解消 👍。
function fetchDataPromise(url) {
return new Promise((resolve, reject) => {
console.log(`Fetching data from ${url} (Promise)...`);
setTimeout(() => {
const success = Math.random() > 0.2; // 80% の確率で成功
if (success) {
const data = { result: `Data from ${url}` };
resolve(data); // 成功時に resolve を呼ぶ
} else {
reject(new Error(`Failed to fetch data from ${url}`)); // 失敗時に reject を呼ぶ
}
}, 1000);
});
}
fetchDataPromise("example.com/dataA")
.then(dataA => { // 成功時の処理 (resolve の値を受け取る)
console.log("Data A:", dataA);
return fetchDataPromise("example.com/dataB"); // 次の Promise を返す
})
.then(dataB => { // 前の then が返した Promise の成功時の処理
console.log("Data B:", dataB);
return "Processing complete!";
})
.then(message => {
console.log("Final message:", message);
})
.catch(error => { // いずれかの Promise で失敗した場合の処理 (reject の値を受け取る)
console.error("An error occurred:", error.message);
})
.finally(() => { // 成功・失敗に関わらず最後に実行される処理 (ES2018)
console.log("Fetch attempt finished.");
});
// Promise.all: 複数の Promise がすべて成功するのを待つ
const promise1 = fetchDataPromise("url1");
const promise2 = fetchDataPromise("url2");
Promise.all([promise1, promise2])
.then(([result1, result2]) => {
console.log("All succeeded:", result1, result2);
})
.catch(error => {
console.error("At least one promise failed:", error.message);
});
// Promise.race: 複数の Promise のうち、最初に完了 (成功または失敗) した結果を得る
Promise.race([promise1, promise2])
.then(firstResult => {
console.log("First settled (resolved):", firstResult);
})
.catch(firstError => {
console.error("First settled (rejected):", firstError.message);
});
async / await (ES2017)
Promise をベースにした、非同期処理を同期処理のように書ける構文糖衣 🌟。async
関数内で await
を使うと、Promise が解決されるまで処理を一時停止する。
// 上記の fetchDataPromise 関数を async/await で使用する例
async function processData() {
try {
console.log("Starting data processing...");
// await は Promise が解決されるまで待つ
const dataA = await fetchDataPromise("example.com/dataAsyncA");
console.log("Async Data A:", dataA);
const dataB = await fetchDataPromise("example.com/dataAsyncB");
console.log("Async Data B:", dataB);
// エラーを発生させる例 (上記の Promise が失敗した場合)
// const dataC = await fetchDataPromise("example.com/dataAsyncC");
// console.log("Async Data C:", dataC);
console.log("Processing finished successfully!");
return "Async Complete";
} catch (error) { // await した Promise が reject されると catch ブロックに移行
console.error("Async Error:", error.message);
// エラー発生時の処理
return "Async Failed";
} finally {
console.log("Async function execution finished.");
}
}
// async 関数は常に Promise を返す
processData()
.then(result => console.log("Result from async function:", result))
.catch(err => console.error("Unhandled error from async function:", err)); // try...catch で捕捉されなかったエラー
// トップレベル await (ES2022): モジュールのトップレベルで await が使える (async 関数で囲む必要がない)
// (環境によるサポート状況に注意)
// const dataTop = await fetchDataPromise("example.com/dataTop");
// console.log("Top-level await result:", dataTop);
🖱️ DOM操作 (Document Object Model)
HTML や XML ドキュメントをプログラムから操作するためのインターフェースです。要素の取得、変更、追加、削除などを行います。
要素の選択・取得
メソッド | 説明 | 戻り値 |
---|---|---|
document.getElementById(id) |
指定されたIDを持つ要素を取得 | Element or null |
document.getElementsByClassName(className) |
指定されたクラス名を持つ要素のコレクションを取得 | HTMLCollection (ライブコレクション) |
document.getElementsByTagName(tagName) |
指定されたタグ名を持つ要素のコレクションを取得 | HTMLCollection (ライブコレクション) |
document.querySelector(selector) |
指定されたCSSセレクタに一致する最初の要素を取得 ✨ | Element or null |
document.querySelectorAll(selector) |
指定されたCSSセレクタに一致するすべての要素のリストを取得 ✨ | NodeList (静的リスト) |
element.closest(selector) |
自身または祖先要素で、指定されたCSSセレクタに一致する最初の要素を取得 | Element or null |
// HTML例: Hello
World
const mainDiv = document.getElementById('main');
const contentParas = document.getElementsByClassName('content'); // HTMLCollection
const allParas = document.getElementsByTagName('p'); // HTMLCollection
const firstContentPara = document.querySelector('#main .content'); // Element
const allContentParas = document.querySelectorAll('.content'); // NodeList
const specialPara = document.querySelector('.special'); // Element
const parentMain = specialPara.closest('#main'); // mainDiv と同じ要素
要素の作成・追加・削除
メソッド | 説明 |
---|---|
document.createElement(tagName) |
指定されたタグ名の新しい要素を作成 |
document.createTextNode(text) |
指定されたテキストを持つ新しいテキストノードを作成 |
parentNode.appendChild(newNode) |
指定された親ノードの最後の子要素としてノードを追加 |
parentNode.insertBefore(newNode, referenceNode) |
指定された親ノードの子要素である参照ノードの前にノードを挿入 |
parentNode.removeChild(childNode) |
指定された子ノードを削除 |
parentNode.replaceChild(newNode, oldNode) |
指定された子ノードを新しいノードで置き換え |
element.append(node1, node2, ...) |
要素の最後の子としてノードや文字列を追加 (複数可) ✨ |
element.prepend(node1, node2, ...) |
要素の最初の子としてノードや文字列を追加 (複数可) ✨ |
element.before(node1, node2, ...) |
要素の直前にノードや文字列を追加 (複数可) ✨ |
element.after(node1, node2, ...) |
要素の直後にノードや文字列を追加 (複数可) ✨ |
element.remove() |
要素自身を削除 ✨ |
// HTML例: - Item 1
const list = document.getElementById('list');
// 新しい li 要素を作成して追加
const newItem = document.createElement('li');
const newText = document.createTextNode('Item 2');
newItem.appendChild(newText);
list.appendChild(newItem); // 末尾に追加
// 新しい要素を作成して先頭に追加 (モダンな方法)
const newerItem = document.createElement('li');
newerItem.textContent = 'Item 0'; // テキスト設定の簡単な方法
list.prepend(newerItem);
// 最初の要素を削除
const firstItem = list.querySelector('li');
if (firstItem) {
list.removeChild(firstItem); // 古い方法
// firstItem.remove(); // モダンな方法
}
属性・テキスト・HTMLの操作
プロパティ/メソッド | 説明 |
---|---|
element.getAttribute(name) |
指定された属性の値を取得 |
element.setAttribute(name, value) |
属性を設定または変更 |
element.removeAttribute(name) |
属性を削除 |
element.hasAttribute(name) |
属性を持っているか確認 |
element.dataset.* |
data-* 属性へのアクセス (例: data-id は element.dataset.id ) |
element.textContent |
要素内のテキストコンテンツを取得または設定 (HTMLタグは解釈されない) 👍 |
element.innerText |
表示されているテキストコンテンツを取得または設定 (スタイルを考慮、パフォーマンス注意) 🤔 |
element.innerHTML |
要素内のHTMLを取得または設定 (セキュリティリスクに注意 ⚠️ XSS) |
// HTML例: Click Me
const link = document.getElementById('link');
console.log(link.getAttribute('href')); // "about:blank"
link.setAttribute('href', 'https://example.com');
link.setAttribute('target', '_blank');
console.log(link.dataset.info); // "some data"
link.dataset.info = "new data";
console.log(link.textContent); // "Click Me"
link.textContent = "Visit Example";
// 注意: innerHTML はサニタイズされていない入力を設定すると危険
// link.innerHTML = "Safe HTML"; // OK
// link.innerHTML = "
"; // 危険!
クラスとスタイルの操作
プロパティ/メソッド | 説明 |
---|---|
element.className |
要素のクラス属性全体を文字列として取得または設定 (上書きに注意) |
element.classList |
クラスを操作するための便利なメソッドを提供する DOMTokenList オブジェクト ✨ |
element.classList.add('className1', ...) |
クラスを追加 |
element.classList.remove('className1', ...) |
クラスを削除 |
element.classList.toggle('className', [force]) |
クラスが存在すれば削除、なければ追加。force が true なら追加、false なら削除。 |
element.classList.contains('className') |
クラスを持っているか確認 |
element.style.property |
インラインスタイルを設定または取得 (例: element.style.color = 'red'; element.style.backgroundColor = 'blue'; キャメルケースで指定) |
window.getComputedStyle(element) |
要素に適用されているすべてのCSSプロパティの値を取得 (読み取り専用) |
// HTML例: Box
const box = document.getElementById('box');
console.log(box.className); // "item active"
box.className = "item"; // "active" が消える
box.classList.add('highlight', 'large'); // class="item highlight large"
box.classList.remove('item'); // class="highlight large"
box.classList.toggle('active'); // class="highlight large active" (active が追加される)
console.log(box.classList.contains('highlight')); // true
box.style.color = 'white';
box.style.padding = '20px';
box.style.backgroundColor = 'navy'; // CSS: background-color
const styles = window.getComputedStyle(box);
console.log(styles.paddingTop); // "20px" (計算された値)
console.log(styles.fontWeight); // "400" (デフォルト値など)
⚡ イベント処理
ユーザーのアクション (クリック、キー入力など) やブラウザの状態変化 (読み込み完了など) に応じて処理を実行する仕組みです。
イベントリスナーの登録と解除
// HTML例:
const button = document.getElementById('myButton');
// イベントハンドラ関数
function handleClick(event) {
console.log('Button clicked!');
console.log('Event type:', event.type); // "click"
console.log('Target element:', event.target); // button 要素
// event.preventDefault(); // イベントのデフォルト動作をキャンセル (例: フォーム送信)
// event.stopPropagation(); // イベントの伝播 (バブリング/キャプチャリング) を停止
}
// イベントリスナーの登録 (推奨される方法) ✨
button.addEventListener('click', handleClick);
// アロー関数を使った登録
button.addEventListener('mouseover', (event) => {
console.log('Mouse over button!');
event.target.style.backgroundColor = 'lightgray';
});
button.addEventListener('mouseout', (event) => {
event.target.style.backgroundColor = ''; // 元に戻す
});
// イベントリスナーの解除 (登録時と同じ関数参照が必要)
// button.removeEventListener('click', handleClick);
// 古い方法 (非推奨: 1つのイベントに1つのハンドラしか登録できない) 🤔
// button.onclick = function() {
// console.log('Button clicked (old way)');
// };
// button.onclick = null; // 解除
イベントオブジェクト
イベントハンドラ関数には、イベントに関する情報を持つイベントオブジェクトが引数として渡されます。
event.type
: イベントの種類 (例: “click”, “keydown”)event.target
: イベントが発生した要素event.currentTarget
: イベントリスナーが登録されている要素 (通常this
と同じ)event.preventDefault()
: イベントのデフォルトの動作 (例: リンクの遷移、フォーム送信) をキャンセルするメソッド。event.stopPropagation()
: イベントの伝播 (親要素へのバブリングなど) を停止するメソッド。- マウスイベント:
event.clientX
,event.clientY
(ウィンドウ座標),event.pageX
,event.pageY
(ドキュメント座標) - キーボードイベント:
event.key
(押されたキー),event.code
(物理キーコード),event.altKey
,event.ctrlKey
,event.shiftKey
(修飾キーの状態)
主なイベントの種類
カテゴリ | イベント名 | 説明 |
---|---|---|
マウスイベント | click |
要素がクリックされた時 |
dblclick |
要素がダブルクリックされた時 | |
mouseover / mouseout |
マウスポインタが要素上/要素外に移動した時 (子要素への移動でも発火) | |
mouseenter / mouseleave |
マウスポインタが要素の境界内/外に移動した時 (子要素への移動では発火しない) 👍 | |
mousemove |
マウスポインタが要素上で移動した時 | |
キーボードイベント | keydown |
キーが押された時 |
keyup |
キーが離された時 | |
keypress |
文字キーが押された時 (非推奨、keydown を推奨) 🤔 |
|
フォームイベント | submit |
フォームが送信される時 (<form> 要素) |
change |
フォーム要素の値が変更され、フォーカスが外れた時 (<input> , <select> , <textarea> ) |
|
input |
フォーム要素の値が変更された時 (リアルタイム、change より頻繁) 👍 |
|
focus / blur |
要素がフォーカスを得た/失った時 | |
ウィンドウ/ドキュメントイベント | load |
ページのリソース (画像など含む) がすべて読み込まれた時 (window ) |
DOMContentLoaded |
HTMLドキュメントの解析とDOMツリーの構築が完了した時 (画像などは待たない) 👍 (document ) |
|
scroll |
ドキュメントや要素がスクロールされた時 (window or 要素) |
イベント伝播 (Event Propagation)
イベントは通常、発生した要素から親要素へと伝播していきます。
- バブリング (Bubbling): デフォルトの挙動。イベントがターゲット要素からルート要素 (
document
,window
) へと順に伝播する。 - キャプチャリング (Capturing): ルート要素からターゲット要素へと順にイベントを捕捉する。
addEventListener
の第3引数にtrue
または{ capture: true }
を指定するとキャプチャフェーズで処理できる。
// HTML:
const parentDiv = document.getElementById('parent');
const childButton = document.getElementById('child');
// バブリングフェーズで実行 (デフォルト)
parentDiv.addEventListener('click', () => {
console.log('Parent clicked (Bubbling)');
});
childButton.addEventListener('click', (event) => {
console.log('Child clicked (Bubbling)');
// event.stopPropagation(); // ここで止めると親のリスナーは呼ばれない
});
// キャプチャリングフェーズで実行
parentDiv.addEventListener('click', () => {
console.log('Parent clicked (Capturing)');
}, true); // 第3引数を true にする
childButton.addEventListener('click', () => {
console.log('Child clicked (Capturing)');
}, { capture: true }); // オブションオブジェクトでも指定可能
// クリック時の出力順:
// Parent clicked (Capturing)
// Child clicked (Capturing)
// Child clicked (Bubbling)
// Parent clicked (Bubbling)
📦 モジュール (Module) (ES6)
コードをファイル単位で分割し、再利用性や保守性を高める仕組みです。export
で公開し、import
で読み込みます。
通常、HTMLファイルから利用する場合は <script type="module" src="main.js"></script>
のように type="module"
属性が必要です。
エクスポート (Export)
export
キーワードを使って、関数、クラス、変数などを他のモジュールから利用できるように公開します。
名前付きエクスポート (Named Export)
複数の要素を名前付きでエクスポートできます。インポート時に同じ名前で指定します。
// utils.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class Helper {
log(message) {
console.log(message);
}
}
const privateVar = "secret"; // エクスポートされない
デフォルトエクスポート (Default Export)
モジュールごとに1つだけ設定できます。インポート時に任意の名前を付けられます。
// greet.js
function greetUser(name) {
return `Hello, ${name}!`;
}
// export default greetUser; // 関数をデフォルトエクスポート
// または無名関数/クラスを直接エクスポート
export default function(name) {
return `こんにちは、${name}さん!`;
}
// export default class MyClass { ... }
インポート (Import)
import
キーワードを使って、他のモジュールからエクスポートされた要素を読み込みます。
// main.js
// 名前付きインポート (utils.js から)
// {} 内にインポートしたい要素名を記述
import { PI, add, Helper } from './utils.js';
// 別名でのインポート (as を使用)
import { add as sum } from './utils.js';
// すべての名前付きエクスポートをオブジェクトとしてインポート
import * as utils from './utils.js';
// デフォルトインポート (greet.js から)
// 任意の名前 (ここでは myGreet) を付けられる
import myGreet from './greet.js';
// デフォルトと名前付きを同時にインポート (あまり一般的ではない)
// import defaultExport, { namedExport } from './module.js';
console.log(PI); // 3.14159
console.log(add(5, 3)); // 8
console.log(sum(10, 20)); // 30
const helper = new Helper();
helper.log("Using Helper class");
console.log(utils.PI); // 3.14159 (名前空間経由)
console.log(utils.add(1, 1)); // 2
console.log(myGreet("太郎")); // こんにちは、太郎さん!
注意点:
import
/export
文は通常、モジュールのトップレベルに記述する必要があります (関数内などでは不可)。- モジュール内のコードはデフォルトで Strict Mode (厳格モード) として扱われます。
- モジュールは一度しか読み込まれません (キャッシュされる)。
- 動的インポート (Dynamic Import)
import()
を使うと、必要なタイミングでモジュールを非同期に読み込むことも可能です。これは Promise を返します。button.addEventListener('click', async () => { try { const module = await import('./heavy-module.js'); module.doSomething(); } catch (error) { console.error("Failed to load module:", error); } });
🚨 エラーハンドリング
プログラム実行中に発生する可能性のあるエラーを適切に処理し、プログラムの意図しない停止を防ぎます。
try...catch...finally 文
エラーが発生する可能性のあるコードを try
ブロックで囲み、エラーが発生した場合の処理を catch
ブロックで記述します。finally
ブロックは、エラーの有無に関わらず最後に必ず実行されます。
function divide(a, b) {
try {
console.log("Attempting division...");
if (b === 0) {
// エラーを意図的に発生させる
throw new Error("Division by zero is not allowed!");
}
const result = a / b;
console.log("Division successful:", result);
return result;
} catch (error) { // エラーオブジェクトを受け取る
console.error("An error occurred:", error.message); // エラーメッセージ
console.error("Error name:", error.name); // エラーの種類 (例: "Error", "TypeError")
// console.error("Stack trace:", error.stack); // スタックトレース (デバッグに有用)
// エラー発生時の処理 (例: デフォルト値を返す、ログを記録する)
return undefined; // または null や特定の値を返す
} finally {
// このブロックは try が成功しても catch が実行されても必ず実行される
console.log("Division attempt finished.");
}
}
divide(10, 2);
// Output:
// Attempting division...
// Division successful: 5
// Division attempt finished.
divide(10, 0);
// Output:
// Attempting division...
// An error occurred: Division by zero is not allowed!
// Error name: Error
// Division attempt finished.
throw 文
カスタムエラーや組み込みのエラーオブジェクトを意図的に発生させます。
function checkAge(age) {
if (typeof age !== 'number') {
throw new TypeError("Age must be a number."); // 組み込みエラー
}
if (age < 0) {
throw new RangeError("Age cannot be negative."); // 組み込みエラー
}
if (age < 18) {
// カスタムエラーオブジェクト (推奨)
class UnderageError extends Error {
constructor(message) {
super(message);
this.name = "UnderageError";
}
}
throw new UnderageError("User is underage.");
// または throw "User is underage."; (非推奨: 文字列や数値も投げられるがエラーオブジェクトが望ましい)
}
console.log("Age is valid.");
}
try {
checkAge(25); // "Age is valid."
checkAge("twenty"); // TypeError catch
// checkAge(-5); // RangeError catch
// checkAge(15); // UnderageError catch
} catch (e) {
console.error(`Caught [${e.name}]: ${e.message}`);
}
主なエラーオブジェクトの種類
Error
: すべてのエラーの基底オブジェクト。SyntaxError
: JavaScript の構文エラー。通常try...catch
では捕捉できない (コード解析時点で発生するため)。ReferenceError
: 存在しない変数や関数を参照しようとした場合のエラー。TypeError
: 値が期待される型でない場合 (例: 関数でないものを呼び出す、null
やundefined
のプロパティにアクセスする)。RangeError
: 数値が許容範囲外の場合 (例: 配列の不正な長さ)。URIError
: URI 関連の関数 (encodeURI
など) の引数が不正な場合。
Promise のエラーハンドリングは .catch()
メソッドや async/await
と組み合わせた try...catch
で行います (非同期処理のセクション参照)。
🕸️ JSON (JavaScript Object Notation)
データ交換フォーマットとして広く使われる、軽量なテキストベースの形式です。JavaScript のオブジェクトリテラルと似た構文を持ちます。
JavaScript オブジェクト ↔ JSON 文字列 の変換
メソッド | 説明 | 注意点 |
---|---|---|
JSON.stringify(value, replacer, space) |
JavaScript の値 (オブジェクトや配列など) を JSON 文字列に変換する。 |
|
JSON.parse(text, reviver) |
JSON 文字列を解析して JavaScript の値 (オブジェクトや配列) を生成する。 |
|
const user = {
id: 101,
name: "Charlie",
email: "charlie@example.com",
isAdmin: false,
lastLogin: new Date(), // Date オブジェクト
settings: undefined, // undefined プロパティ
greet: function() {}, // 関数
[Symbol('secret')]: 'value' // Symbol キー
};
// オブジェクト -> JSON 文字列
// undefined, 関数, Symbol は含まれない
// Date は ISO 8601 形式の文字列になる
const jsonString = JSON.stringify(user);
console.log(jsonString);
// 出力例: {"id":101,"name":"Charlie","email":"charlie@example.com","isAdmin":false,"lastLogin":"2025-04-03T09:40:00.000Z"}
// 整形して出力 (インデント = 2スペース)
const prettyJsonString = JSON.stringify(user, null, 2);
console.log(prettyJsonString);
/*
出力例:
{
"id": 101,
"name": "Charlie",
"email": "charlie@example.com",
"isAdmin": false,
"lastLogin": "2025-04-03T09:40:00.000Z"
}
*/
// replacer 関数の例 (name プロパティだけ大文字にする)
const replacerFunc = (key, value) => {
if (key === 'name') {
return value.toUpperCase();
}
if (typeof value === 'function' || typeof value === 'undefined' || typeof value === 'symbol') {
return undefined; // 明示的に除外
}
return value;
};
const replacedJson = JSON.stringify(user, replacerFunc, 2);
console.log(replacedJson);
/*
出力例:
{
"id": 101,
"name": "CHARLIE",
"email": "charlie@example.com",
"isAdmin": false,
"lastLogin": "2025-04-03T09:40:00.000Z"
}
*/
// JSON 文字列 -> オブジェクト
const jsonToParse = '{"id":102,"name":"Dana","isActive":true,"tags":["a","b"]}';
const parsedObject = JSON.parse(jsonToParse);
console.log(parsedObject); // { id: 102, name: 'Dana', isActive: true, tags: [ 'a', 'b' ] }
console.log(parsedObject.name); // "Dana"
// reviver 関数の例 (日付文字列を Date オブジェクトに戻す)
const jsonWithDate = '{"event":"Meeting","date":"2025-05-10T10:00:00.000Z"}';
const reviverFunc = (key, value) => {
if (key === 'date' && typeof value === 'string') {
// ISO 8601 形式の日付文字列を Date オブジェクトに変換
const datePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
if (datePattern.test(value)) {
return new Date(value);
}
}
return value;
};
const parsedWithDate = JSON.parse(jsonWithDate, reviverFunc);
console.log(parsedWithDate); // { event: 'Meeting', date: Date object }
console.log(parsedWithDate.date.getFullYear()); // 2025
JSON の構文ルール:
- データは名前/値のペア (オブジェクト:
{"key": "value"}
)。キーは常にダブルクォートで囲まれた文字列。 - データは順序付けられた値のリスト (配列:
[value1, value2]
)。 - 値として使えるのは、文字列 (ダブルクォート)、数値、
true
,false
,null
、オブジェクト、配列。 - コメントは許可されない。
🔍 正規表現 (Regular Expression)
文字列のパターンマッチングを行うための表現式です。文字列の検索、置換、抽出、検証などに使われます。
正規表現の作成
// リテラル記法 (推奨: パターンが静的な場合)
const regex1 = /abc/; // "abc" という文字列にマッチ
const regex2 = /hello/i; // "hello" に大文字小文字を区別せずにマッチ (i フラグ)
// RegExp コンストラクタ (パターンが動的に変わる場合や文字列から生成する場合)
const pattern = "world";
const flags = "gi"; // g: グローバル検索, i: 大文字小文字無視
const regex3 = new RegExp(pattern, flags); // /world/gi と同じ
// 特殊文字をエスケープする必要がある場合
const variablePattern = "a.b"; // "." は特殊文字なのでエスケープが必要
const regex4 = new RegExp(variablePattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')); // /a\.b/ と同じ
主な正規表現メソッド
メソッド | 説明 | 戻り値 |
---|---|---|
RegExp.prototype.test(str) |
文字列が正規表現にマッチするかどうかを判定する。 | Boolean |
RegExp.prototype.exec(str) |
文字列から正規表現にマッチする部分を検索し、結果を配列 (詳細情報付き) または null で返す。g フラグがあると、呼び出すたびに次のマッチを検索する (lastIndex プロパティが更新される)。 |
マッチ情報の配列 or null |
String.prototype.match(regexp) |
文字列と正規表現のマッチ結果を配列で返す。g フラグがない場合は exec と似た結果 (キャプチャグループ含む)、g フラグがある場合は全てのマッチ文字列の配列 (キャプチャグループ含まず)。 |
マッチ情報の配列 or null (gなし), マッチ文字列の配列 or null (gあり) |
String.prototype.search(regexp) |
文字列内で正規表現に最初にマッチする位置のインデックスを返す (見つからない場合は -1)。g フラグは無視される。 |
インデックス or -1 |
String.prototype.replace(regexp|substr, newSubstr|function) |
文字列内で正規表現または部分文字列にマッチする部分を、新しい文字列または関数の戻り値で置き換える。g フラグがあると全てのマッチを置換。 |
置換後の新しい文字列 |
String.prototype.split(separator, limit) |
文字列を、指定された区切り文字 (文字列または正規表現) で分割し、部分文字列の配列を返す。 | 部分文字列の配列 |
const text = "The quick brown fox jumps over the lazy dog. The fox is quick.";
const pattern = /quick/g; // "quick" をグローバル検索
const patternIgnoreCase = /fox/gi; // "fox" を大文字小文字無視でグローバル検索
const patternWithGroup = /(\w+) fox/; // 単語 + " fox" にマッチ (単語をキャプチャ)
// test()
console.log(/quick/.test(text)); // true
console.log(/slow/.test(text)); // false
// exec()
const regex = /T(h)(e)/g; // 'T', 'h', 'e' にマッチし、'h'と'e'をキャプチャ
let match;
while ((match = regex.exec(text)) !== null) {
console.log(`Found "${match[0]}" at index ${match.index}. Captured: ${match[1]}, ${match[2]}`);
console.log(`Next search starts at ${regex.lastIndex}`);
}
// Found "The" at index 0. Captured: h, e / Next search starts at 3
// Found "the" at index 31. Captured: h, e / Next search starts at 34
// match()
console.log(text.match(/the/i));
// ['the', index: 31, input: '...', groups: undefined] (g なし、最初のマッチ詳細)
console.log(text.match(patternIgnoreCase));
// ['fox', 'fox'] (g あり、全てのマッチ文字列)
console.log(text.match(patternWithGroup));
// ['brown fox', 'brown', index: 10, input: '...', groups: undefined] (g なし、キャプチャグループ含む)
// search()
console.log(text.search(/brown/)); // 10
console.log(text.search(/Lazy/)); // -1 (大文字小文字区別)
console.log(text.search(/Lazy/i)); // 35 (i フラグでマッチ)
// replace()
console.log(text.replace("fox", "cat")); // "The quick brown cat jumps over the lazy dog..." (最初の "fox" のみ)
console.log(text.replace(/fox/g, "cat")); // "The quick brown cat jumps over the lazy dog. The cat is quick." (全ての "fox")
console.log(text.replace(patternIgnoreCase, "CAT")); // "The quick brown CAT jumps over the lazy dog. The CAT is quick." (大文字小文字無視で全て置換)
console.log(text.replace(/(\w+) (\w+)/g, '$2, $1')); // "quick The, brown quick, fox brown, ..." (単語の順序入れ替え)
console.log(text.replace(/quick/gi, (matched) => matched.toUpperCase())); // "The QUICK brown fox jumps over the lazy dog. The fox is QUICK." (マッチ部分を大文字に)
// split()
console.log("apple,banana,orange".split(",")); // ['apple', 'banana', 'orange']
console.log("one two three".split(/\s+/)); // ['one', 'two', 'three'] (スペースで分割)
console.log("item1|item2||item3".split(/\|/)); // ['item1', 'item2', '', 'item3']
主要なメタ文字と量指定子
記号 | 意味 |
---|---|
メタ文字 | |
. | 改行文字 (\n , \r ) 以外の任意の1文字 (s フラグで改行も含む) |
\d | 任意の数字 ([0-9] と等価) |
\D | 数字以外の任意の文字 ([^0-9] と等価) |
\w | 英数字またはアンダースコア ([A-Za-z0-9_] と等価) |
\W | 英数字・アンダースコア以外の任意の文字 ([^A-Za-z0-9_] と等価) |
\s | 任意の空白文字 (スペース、タブ、改行など) |
\S | 空白文字以外の任意の文字 |
[...] | 角括弧内のいずれか1文字 (例: [abc] は ‘a’ or ‘b’ or ‘c’) |
[^...] | 角括弧内を除く任意の1文字 (例: [^abc] は ‘a’, ‘b’, ‘c’ 以外) |
^ | 行または文字列の先頭 (m フラグで行頭) |
$ | 行または文字列の末尾 (m フラグで行末) |
\b | 単語境界 (単語の開始または終了位置) |
\B | 非単語境界 |
( ) | グループ化 (キャプチャグループ)。(?:...) でキャプチャしないグループ。 |
| | OR 条件 (例: a|b は ‘a’ または ‘b’) |
量指定子 | |
* | 直前の要素の0回以上の繰り返し (貪欲マッチ) |
+ | 直前の要素の1回以上の繰り返し (貪欲マッチ) |
? | 直前の要素の0回または1回の繰り返し (貪欲マッチ) |
{n} | 直前の要素のちょうど n 回の繰り返し |
{n,} | 直前の要素の n 回以上の繰り返し |
{n,m} | 直前の要素の n 回以上 m 回以下の繰り返し |
*? , +? , ?? , {n,m}? | 量指定子の後に ? を付けると、最小限のマッチ (非貪欲/怠惰マッチ) になる |
フラグ | |
g | グローバル検索 (最初にマッチした後も検索を続ける) |
i | 大文字小文字を無視する |
m | 複数行モード (^ と $ が行の先頭/末尾にマッチするようになる) |
u | Unicode モード (サロゲートペアなどを正しく扱う) |
y | スティッキーモード (lastIndex プロパティで指定された位置からのみマッチを試みる) |
s | dotAll モード (. が改行文字にもマッチするようになる) (ES2018) |
✨ その他便利な機能 (ES6以降中心)
コードをより簡潔かつ効率的に書くための比較的新しい機能です。
スプレッド構文 (Spread Syntax) ...
イテラブルオブジェクト (配列、文字列など) やオブジェクトを展開します。
// 配列の展開
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, 0, ...arr2]; // [1, 2, 3, 0, 4, 5, 6]
const copiedArray = [...arr1]; // 配列の浅いコピー
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6 (配列要素を引数として展開)
// 文字列の展開
const str = "hello";
const chars = [...str]; // ['h', 'e', 'l', 'l', 'o']
// オブジェクトの展開 (ES2018)
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const mergedObject = { ...obj1, ...obj2 }; // { a: 1, b: 3, c: 4 } (obj2のbで上書き)
const copiedObject = { ...obj1 }; // オブジェクトの浅いコピー
分割代入 (Destructuring Assignment)
配列やオブジェクトから値を取り出して、個別の変数に代入します。
// 配列の分割代入
const colors = ["red", "green", "blue"];
const [firstColor, secondColor] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
const [a, , c, d = "yellow"] = colors; // 要素のスキップ、デフォルト値
console.log(a); // "red"
console.log(c); // "blue"
console.log(d); // "yellow" (元の配列にないためデフォルト値)
// Rest パターンとの組み合わせ
const [x, ...rest] = [10, 20, 30, 40];
console.log(x); // 10
console.log(rest); // [20, 30, 40]
// 関数の引数での分割代入
function printCoords([lat, lon]) {
console.log(`Latitude: ${lat}, Longitude: ${lon}`);
}
printCoords([35.68, 139.76]);
// オブジェクトの分割代入
const user = { id: 42, name: "Alice", age: 30, city: "London" };
const { name, age } = user;
console.log(name); // "Alice"
console.log(age); // 30
// 異なる変数名への代入、デフォルト値
const { id: userId, city = "Unknown", country = "UK" } = user;
console.log(userId); // 42
console.log(city); // "London" (元のオブジェクトの値を使用)
console.log(country); // "UK" (元のオブジェクトにないためデフォルト値)
// ネストしたオブジェクトの分割代入
const data = { info: { score: 95, rank: 1 } };
const { info: { score } } = data;
console.log(score); // 95
// 関数の引数での分割代入 (オブジェクト)
function displayUser({ name, age }) {
console.log(`User: ${name}, Age: ${age}`);
}
displayUser(user);
テンプレートリテラル (Template Literals)
バッククォート (`
) を使って文字列を定義します。埋め込み式 (${expression}
) や複数行文字列が簡単に扱えます。
const userName = "Bob";
const userAge = 25;
// 埋め込み式
const message = `Hello, my name is ${userName} and I am ${userAge} years old.`;
console.log(message); // "Hello, my name is Bob and I am 25 years old."
// 複数行文字列
const multiLine = `This is the first line.
This is the second line.
Indentation is preserved.`;
console.log(multiLine);
// タグ付きテンプレートリテラル (高度な利用法)
function highlight(strings, ...values) {
let result = '';
strings.forEach((str, i) => {
result += str;
if (values[i]) {
result += `${values[i]}`;
}
});
return result;
}
const highlightedMessage = highlight`User ${userName} (age ${userAge}) logged in.`;
console.log(highlightedMessage);
// "User Bob (age 25) logged in."
Optional Chaining Operator (?.) (ES2020)
オブジェクトのプロパティにアクセスする際、途中のプロパティが null
または undefined
でもエラーにならず、undefined
を返します。
const userProfile = {
name: "Carol",
address: {
street: "123 Main St",
city: "Anytown"
},
// contact: null
getContactInfo() {
return this.contact?.email;
}
};
// 通常のアクセスではエラーになる場合がある
// const zipCode = userProfile.address.zipCode; // OK if address exists
// const phone = userProfile.contact.phone; // TypeError: Cannot read properties of undefined (reading 'phone')
// Optional Chaining を使用
const zipCode = userProfile.address?.zipCode; // undefined (address は存在するが zipCode がない)
const street = userProfile.address?.street; // "123 Main St"
const phone = userProfile.contact?.phone; // undefined (contact が undefined/null)
const country = userProfile.address?.country?.code; // undefined (ネストして使用可能)
// メソッド呼び出しにも使える
const contactInfo = userProfile.getContactInfo?.(); // undefined (getContactInfo内でも ?. を使用)
// 配列要素へのアクセス
const firstHobby = userProfile.hobbies?.[0]; // undefined (hobbies がない)
Nullish Coalescing Operator (??) (ES2020)
左辺が null
または undefined
の場合に右辺の値を返します。それ以外の偽値 (0
, ''
, false
, NaN
) では左辺の値を返します。(||
演算子との違い)
const settings = {
timeout: 0, // タイムアウト 0ms は有効な値
retries: null,
theme: '' // 空文字列も有効なテーマ設定の可能性
};
// || 演算子の場合 (0 や '' も偽値として扱われる)
const timeoutValue = settings.timeout || 5000; // 5000 (0 が偽値のため右辺が採用される) 🤔
const themeValue = settings.theme || 'dark'; // 'dark' ('' が偽値のため右辺が採用される) 🤔
// ?? 演算子の場合 (null と undefined のみ右辺を採用) 👍
const timeoutValueCoalescing = settings.timeout ?? 5000; // 0 (左辺が null/undefined でないので左辺を採用)
const retriesValue = settings.retries ?? 3; // 3 (左辺が null なので右辺を採用)
const themeValueCoalescing = settings.theme ?? 'dark'; // '' (左辺が null/undefined でないので左辺を採用)
const undefinedValue = settings.username ?? 'Guest'; // 'Guest' (settings.username が undefined のため右辺を採用)
コメント