JavaScript | ラッパーオブジェクトとプリミティブ型

javascrpit JavaScript
スポンサーリンク

コードレビューでよく見る「ラッパー関連のバグ」サンプル集

バグ1:new Boolean(false) が常に真になる

// ❌ NG
const isActive = new Boolean(false);

if (isActive) {
  console.log("Active!"); // 実行される ❗
} else {
  console.log("Inactive");
}
JavaScript

問題点

  • new Boolean(false)オブジェクト
    → オブジェクトは常に truthy なので、条件式は必ず真。

正しい書き方

const isActive = false;
// または
const isActive = Boolean(false);
JavaScript

バグ2:new Number(0) が falsy ではない

// ❌ NG
const count = new Number(0);

if (count) {
  console.log("Has count"); // 実行される ❗
} else {
  console.log("No count");
}
JavaScript

問題点

  • new Number(0) はオブジェクト → truthy。
  • 中の数値 0 が falsy でも意味がない。

修正版

const count = 0;
if (count) {
  // falsy の 0 なら else に入る
}
JavaScript

バグ3:new String("") も truthy(空文字ではないと判定される)

// ❌ NG
const name = new String("");

if (name) {
  console.log("Has name"); // 実行される ❗
}
JavaScript

問題点

  • new String("") はオブジェクト → truthy。
  • 空文字チェックが破壊される。

修正版

const name = "";
if (name) {
  // falsy なので実行されない(正しい挙動)
}
JavaScript

バグ4:typeof で判定しても「object」になる

// ❌ NG
const id = new Number(10);

if (typeof id === "number") {
  console.log("This is a number"); // 実行されない ❗
}
JavaScript

問題点

  • typeof new Number(10)"object"
    → 型チェックが失敗する。

修正版

const id = 10;
if (typeof id === "number") {
  console.log("This is a number"); // ✅
}
JavaScript

バグ5:比較演算子の混乱(== が一見動く)

// ❌ NG
const n = new Number(5);

console.log(n == 5);   // true (型変換が起こる)
console.log(n === 5);  // false ❗
JavaScript

問題点

  • == は内部的に n.valueOf() を呼び出してプリミティブに変換してしまう。
  • 結果的に 比較が通ってしまう ため、型の違いに気付きにくい。

修正版

const n = 5;
console.log(n === 5); // ✅
JavaScript

バグ6:プロパティが保持されない(暗黙ラッパー)

// ❌ NG
let s = "hello";
s.custom = 123;

console.log(s.custom); // undefined ❗
JavaScript

問題点

  • "hello" はプリミティブ → 一時オブジェクトにプロパティを付けても破棄される。

修正版

let s = new String("hello");
s.custom = 123;
console.log(s.custom); // 123 ✅
JavaScript

※ただし通常、文字列にプロパティを持たせる必要はないので、
オブジェクトで管理した方がよい。

バグ7:ラッパー経由の JSON 変換で意図しない結果

// ❌ NG
const data = {
  count: new Number(5),
  active: new Boolean(true)
};
console.log(JSON.stringify(data));
// 出力: {"count":{},"active":{}} ❗
JavaScript

問題点

  • Number/Boolean オブジェクトは JSON.stringify 時に空オブジェクト {} になる。

修正版

const data = {
  count: 5,
  active: true
};
console.log(JSON.stringify(data)); // {"count":5,"active":true} ✅
JavaScript

バグ8:instanceof の誤用

// ❌ NG
const str = "test";

if (str instanceof String) {
  console.log("String type"); // 実行されない ❗
}
JavaScript

問題点

  • プリミティブ "test"String オブジェクトではない。
  • instanceof Stringfalse

修正版

if (typeof str === "string") {
  console.log("String type"); // ✅
}
JavaScript

バグ9:数値のプロパティアクセスで構文エラー

// ❌ NG
console.log(5.toFixed(2)); // SyntaxError ❗
JavaScript

修正版

console.log((5).toFixed(2)); // "5.00"
console.log(5..toFixed(2));  // "5.00"
JavaScript

解説:
5. は小数点とみなされるため、2つ目の . が必要。

バグ10:Object() による暗黙のラッパーが意図しない結果を出す

// ❌ NG
const wrapped = Object("abc");

console.log(typeof wrapped); // "object"
console.log(wrapped instanceof String); // true
console.log(wrapped + "def"); // "abcdef" ✅だが挙動が特殊
JavaScript

問題点

  • Object() にプリミティブを渡すと、対応するラッパーが生成される。
  • そのため typeof"object" に変わり、型チェックが狂う。

コードレビューでのチェックリスト

チェック項目目的
new Boolean / new Number / new String を使っていないか不要なラッパー作成を防ぐ
typeof チェックで "object" が返っていないかラッパー検出
JSON 化して {} になっていないかラッパー混入の兆候
比較に == を使っていないか暗黙変換による誤判定防止
空文字・0・false チェックでおかしい挙動をしていないかラッパー truthy 問題検出

まとめ

  • 絶対に使わない!new Number(), new Boolean(), new String()
  • 安全な変換方法: Number(), String(), Boolean()new なし)
  • プリミティブで十分。
    JavaScript は必要時に自動でラッパーを作る(オートボクシング)。
  • ラッパーを混ぜると型チェック・比較・真偽判定・JSON化が壊れる。
タイトルとURLをコピーしました