Open6

JavaScript MDNの気になる部分を読んでみた

yuyayuya

9/25

関数の引数

デフォルト引数

JavaScript は、関数の引数はデフォルトで undefined となる。
引数が渡って来なかった場合にデフォルト引数を使うと undefindを回避できる

function multiply(a, b = 1) {
  return a * b;
}

console.log(multiply(10)); // 10

残余引数

不特定多数の引数を配列のように表すことができる

function multiply(multiplier, ...theArgs) {
  return theArgs.map((x) => multiplier * x);
}

const arr = multiply(10, 2, 3, 4, 5, 6);
console.log(arr); // [20, 30, 40, 50, 60]

独自の this を持たない

ここはよくわからなかった
ただ、thisを固定したいときはbind関数を使うと良い

アロー関数は自身のthisを持たない

function Human() {
  this.age = 0;

  setInterval(() => {
    this.age++; // `this` は的確に human オブジェクトを参照する
  }, 1000);
}

const p = new Human();
yuyayuya

9/27

代入連鎖の防止

非推奨な書き方。あんまりやらないと思うけど
const x = y = z = f();

typeof

nullのtypeofの結果は要注意

typeof null; // "object" を返す

instanceof

実行時にオブジェクトの型を確認する必要があるときに使用

const theDay = new Date(2000, 07, 30);
if (theDay instanceof Date) {
  console.log("this is Date Object!!");
}

プロパティアクセサー

ドット記法 or ブラケット記法
プロジェクトや自分の好みに合わせる

// 両方OK
object.property;
object["property"];
yuyayuya

9/28

数値と文字列

文字列

よく使うメソッドまとめ

// 分解系
split(separator) // 文字列を分割して配列にする
slice(start, end) // 文字列の一部を切り出し
substring(start, end) // 文字列の一部を切り出し
trim() // 前後の空白を除去
// 変換系
toLowerCase() // 小文字に変換
toUpperCase() // 大文字に変換
// 問い合わせ系
charAt(index) // 指定位置の文字を取得
at(index) // 指定位置の文字を取得(負のインデックスも可)
// 検索系
indexOf(searchString) // 文字列の位置を前から検索
includes(searchString) // 文字列が含まれるかを判定
startsWith(searchString) // 指定文字列で始まるかを判定
endsWith(searchString) // 指定文字列で終わるかを判定
// 合成系
concat(string) // 文字列を連結(ただし+演算子の方が一般的)
repeat(count) // 文字列を指定回数繰り返し
padStart(length, padString) // 文字列の先頭を指定文字で埋める
padEnd(length, padString) // 文字列の末尾を指定文字で埋める
yuyayuya

正規表現

これむずいっすね〜
簡単なものとこれ覚えておくと楽ってものから

簡単なもの

// 完全一致
/hello/              // "hello"という文字列
/123/                // "123"という数字

/.../                // 任意の1文字
/h.llo/              // "hello", "hallo", "hxllo" など

/a*/                 // aが0回以上
/a+/                 // aが1回以上  
/a?/                 // aが0回または1回

/[abc]/              // a, b, c のいずれか
/[a-z]/              // 小文字
/[A-Z]/              // 大文字
/[0-9]/              // 数字
/[^abc]/             // a, b, c 以外

/\d/                 // 数字 [0-9]
/\w/                 // 英数字 [a-zA-Z0-9_]
/\s/                 // 空白文字
/\D/                 // 数字以外
/\W/                 // 英数字以外
/\S/                 // 空白以外

/^hello/             // 行の始まり
/world$/             // 行の終わり
/^hello$/            // 完全一致

覚えておくと便利

// 日本語の文字
/[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]/

// 半角英数字のみ
/^[a-zA-Z0-9]+$/

// パスワード(8文字以上、英数字含む)
/^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{8,}$/

// URLの形式
/^https?:\/\/[\w.-]+\.[\w]{2,}(\/.*)?$/

// IPアドレス(簡易版)
/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
yuyayuya

インデックス付きコレクション

findLast() メソッドは、callback が true を返した最後の項目を返す

const a1 = ["a", 1, "b", 2, "c", 3];
const i = a1.findLast((item) => typeof item === "number");
console.log(i); // 3

findIndex() メソッドは、callback が true を返した最初の項目のインデックスを返す。

const a1 = ["a", 1, "b", 2, "c", 3];
const i = a1.findIndex((item) => typeof item === "number");
console.log(i); // 1

every() はコールバック関数 callback が配列内のすべてのアイテムで true を返す場合に true を返す。

function isNumber(value) {
  return typeof value === "number";
}
const a1 = [1, 2, 3];
console.log(a1.every(isNumber)); // true
const a2 = [1, "2", 3];
console.log(a2.every(isNumber)); // false

some() はコールバック関数 callback が配列内の少なくとも一つのアイテムで true を返す場合に true を返す。

function isNumber(value) {
  return typeof value === "number";
}
const a1 = [1, 2, 3];
console.log(a1.some(isNumber)); // true
const a2 = [1, "2", 3];
console.log(a2.some(isNumber)); // true
const a3 = ["1", "2", "3"];
console.log(a3.some(isNumber)); // false

みんなが一回はえ?これどういうこと?ってなるreduce

const a = [10, 20, 30];
const total = a.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  0,
);
console.log(total); // 60

reduceRight()は開始位置が最後からって部分がミソ

疎配列

意外とどゆこと?ってなりがちな挙動

// Array コンストラクター:
const a = Array(5); // [ <5 つの空の項目> ]

// 配列リテラルの連続したカンマ:
const b = [1, 2, , , 5]; // [ 1, 2, <2 つの空の項目>, 5 ]

// array.length より大きいインデックスを持つスロットを直接設定:
const c = [1, 2];
c[4] = 5; // [ 1, 2, <2 つの空の項目>, 5 ]

// .length を直接設定して配列を延長する:
const d = [1, 2];
d.length = 5; // [ 1, 2, <3 つの空の項目> ]

// 要素の削除:
const e = [1, 2, 3, 4, 5];
delete e[2]; // [ 1, 2, <1 つの空の項目>, 4, 5 ]
yuyayuya

キー付きコレクション

MapとObject

  • Map を選ぶ: キーが動的、プリミティブ値のキー、頻繁な追加削除、サイズ管理が必要
  • Object を選ぶ: 固定スキーマ、JSON連携、メソッド定義、プロトタイプ継承が必要

Mapの使用例

// ユーザー入力に基づいて動的にキーを追加
const userPreferences = new Map();

function savePreference(key, value) {
  userPreferences.set(key, value);
}

// 実行時に決まるキー
savePreference('theme', 'dark');
savePreference('language', 'ja');
savePreference('fontSize', 16);

console.log(userPreferences.get('theme')); // 'dark'
// すべてのキーが文字列、すべての値が数値
const wordCount = new Map([
  ['apple', 5],
  ['banana', 3],
  ['cherry', 8]
]);

// イテレーションが簡単
for (const [word, count] of wordCount) {
  console.log(`${word}: ${count}`);
}

// サイズの取得が簡単
console.log(`合計: ${wordCount.size}個の単語`);
// 数値をキーとして使用
const statusCodes = new Map([
  [200, 'OK'],
  [404, 'Not Found'],
  [500, 'Internal Server Error']
]);

console.log(statusCodes.get(404)); // 'Not Found'

// Objectだと文字列に変換されてしまう
const statusObj = {
  200: 'OK',
  404: 'Not Found'
};
console.log(Object.keys(statusObj)); // ['200', '404'] - 文字列になる

// オブジェクトをキーとして使用(Mapのみ可能)
const metadata = new Map();
const userObj = { id: 1, name: 'Alice' };
const productObj = { id: 101, name: 'Laptop' };

metadata.set(userObj, { lastLogin: '2025-09-29' });
metadata.set(productObj, { stock: 50 });

console.log(metadata.get(userObj)); // { lastLogin: '2025-09-29' }

Objectの使用例

// ユーザー情報のような固定スキーマ
const user = {
  id: 12345,
  name: '田中太郎',
  email: 'tanaka@example.com',
  age: 30,
  isActive: true,
  
  // メソッドも定義できる
  getFullInfo() {
    return `${this.name} (${this.email})`;
  }
};

console.log(user.name); // ドット記法でアクセス
console.log(user.getFullInfo()); // メソッド呼び出し
// 設定ファイルの読み書き
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retryCount: 3,
  features: {
    enableCache: true,
    enableLogging: false
  }
};

// JSON化が簡単
const jsonString = JSON.stringify(config);
console.log(jsonString);

// パース後もObjectとして扱える
const parsed = JSON.parse(jsonString);
console.log(parsed.apiUrl);
// クラスベースの設計
class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(`${this.name}が鳴いています`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
  
  speak() {
    console.log(`${this.name}がワンワン吠えています`);
  }
}

const dog = new Dog('ポチ', '柴犬');
dog.speak(); // ポチがワンワン吠えています