この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:6
ページ更新者:ぼうず
更新日時:2026-06-11 07:29:05

タイトル: シングルクォーテーションとダブルクォーテーションの違い
SEOタイトル: JavaScript の "" と '' の違い (仕様上は等価 / テンプレートリテラル / JSON / Lint)

この記事の要点
  • JavaScript では 'hello'"hello"仕様上完全に等価。型もコストも同じ
  • 使い分けはチームの規約 (Prettier/ESLint) 次第。Airbnb は "'" (シングル) 推奨
  • バックティック `...` はテンプレートリテラル。${expr} 補間と複数行が可能
  • JSON はダブルクォート必須'key': 1 はパースエラー
  • HTML 属性に埋め込むときは外側と逆を選ぶとエスケープ不要に

結論: 仕様上は完全等価

JavaScript の文字列リテラルは '...'"..." のどちらでも 同じ string 型の値を生成します。実行コストもメモリも違いはありません。

const a = 'hello';
const b = "hello";

console.log(a === b);           // true
console.log(typeof a);          // 'string'
console.log(typeof b);          // 'string'
console.log(a.length === b.length); // true

// 連結も同じ
console.log('foo' + "bar");     // 'foobar'

では何が違うのか

観点シングル 'ダブル "バックティック `
仕様上の挙動同じ同じテンプレートリテラル (拡張)
変数補間 ${x}不可不可
複数行不可 (改行は \n)不可
JSON で使えるか不可 (パースエラー)必須不可
HTML 属性内attr="..." の中で安全attr='...' の中で安全属性内では不要
慣習 (Airbnb/Standard)★ 推奨許容補間時のみ
慣習 (Prettier 既定)★ 既定 singleQuote: true
4.0 までは "

テンプレートリテラル: バックティックの真価

変数を埋め込みたい / 複数行を書きたいときは、ES2015+ のバックティック ` ` を使います。

const name = 'Alice';
const age = 30;

// ❌ 古いやり方 (連結)
const msg1 = 'Hello, ' + name + '! You are ' + age + ' years old.';

// ✅ テンプレートリテラル
const msg2 = `Hello, ${name}! You are ${age} years old.`;

// 複数行もそのまま書ける
const html = `
  <div class="user">
    <h2>${name}</h2>
    <p>Age: ${age}</p>
  </div>
`;

// 式も書ける
const tax = `Total: $${(price * 1.1).toFixed(2)}`;

// タグ付きテンプレート (高度)
function tag(strings, ...values) {
  return strings.raw.join('|') + ' / ' + values.join(',');
}
tag`Hi ${name} - ${age}`;

JSON はダブルクォート固定

JSON 仕様 (RFC 8259) では文字列もキーも ダブルクォート必須。シングルは構文エラーになります。

// ✅ 正しい JSON
const ok = '{"name":"Alice","age":30}';
JSON.parse(ok);          // { name: 'Alice', age: 30 }

// ❌ シングルクォートはエラー
const ng = "{'name':'Alice'}";
JSON.parse(ng);          // SyntaxError: Unexpected token ' in JSON at position 1

// JavaScript のオブジェクトリテラルとは別物
const obj = { name: 'Alice', age: 30 };   // ← JS なので OK
const jsonStr = JSON.stringify(obj);
// → '{"name":"Alice","age":30}' (常にダブル)

HTML 属性に埋め込むときの選び方

HTML 属性は "..." または '...' どちらでも書けます。外側と逆のクォートを内側で使うとエスケープを減らせます。

// ✅ HTML 属性が " なら JS は ' に
const html1 = '<a href="https://example.com" onclick="alert(\'hi\')">link</a>';
const html2 = `<a href="https://example.com" onclick='alert("hi")'>link</a>`;

// ❌ どちらも " だとエスケープ地獄
const ng = "<a href=\"https://example.com\" onclick=\"alert(\\\"hi\\\")\">link</a>";

// React / JSX
// 属性値は {} で式を渡せばクォート問題は出ない
const Btn = <button onClick={() => alert("hi")}>Go</button>;

エスケープシーケンスはどちらも同じ

const s1 = 'line1\nline2\ttab';
const s2 = "line1\nline2\ttab";
console.log(s1 === s2);   // true

// 含めたいクォートを逆で囲うとエスケープ不要
const a = "Bob's car";       // OK
const b = 'Bob\'s car';      // OK だがエスケープが必要
const c = 'She said "hi"';   // OK
const d = "She said \"hi\""; // OK だがエスケープが必要

// Unicode
const heart = '❤';      // ❤
const emoji = '\u{1F600}';   // 😀 (ES2015+)

ESLint / Prettier での強制

// .eslintrc.json - シングル強制
{
  "rules": {
    "quotes": ["error", "single", {
      "avoidEscape": true,
      "allowTemplateLiterals": true
    }]
  }
}

// .prettierrc - Prettier (デフォルトは "single": false = ダブル)
{
  "singleQuote": true,
  "jsxSingleQuote": false
}

大事なのはチーム内で統一すること。git diff のノイズを減らすために、必ず Lint で自動修正できる状態を作っておきます。

Python / PHP / Rust との違い

言語
JavaScript完全等価。バックティックでテンプレ
Python完全等価。三重 """ / ''' で複数行。f-string f".." で補間
PHP違いあり: ".."$var 補間あり、'..' は無し
Rust / Go / Java".." は文字列、'..'char (1文字) なので意味が違う
Bash".." は変数展開あり、'..' は無し (PHP と同じ系)

FAQ

Q: どちらが速い?
A: 同じです。エンジン (V8/SpiderMonkey) は同じパースツリーに変換します。

Q: いつバックティックを使うべき?
A: 変数補間が必要なときと複数行のとき。それ以外で乱用すると Lint が指摘します (prefer-template)。

Q: minify 後はどうなる?
A: Terser などは出力時に統一します (既定は ")。バンドル後はチームの好みに依存しません。