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

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

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li>JavaScript では <code>'hello'</code> と <code>"hello"</code> は<strong>仕様上完全に等価</strong>。型もコストも同じ</li><li>使い分けは<strong>チームの規約 (Prettier/ESLint)</strong> 次第。Airbnb は "'" (シングル) 推奨</li><li>バックティック <code>`...`</code> はテンプレートリテラル。<code>${expr}</code> 補間と複数行が可能</li><li><strong>JSON はダブルクォート必須</strong>。<code>'key': 1</code> はパースエラー</li><li>HTML 属性に埋め込むときは外側と逆を選ぶとエスケープ不要に</li></ul></td></tr></table>
<h2>結論: 仕様上は完全等価</h2>

<p>JavaScript の文字列リテラルは <code>'...'</code> と <code>"..."</code> のどちらでも <strong>同じ <code>string</code> 型の値</strong>を生成します。実行コストもメモリも違いはありません。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const a = &apos;hello&apos;;
const b = "hello";

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

// 連結も同じ
console.log(&apos;foo&apos; + "bar");     // &apos;foobar&apos;</code></pre>
<h2>では何が違うのか</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>観点</th><th>シングル <code>'</code></th><th>ダブル <code>"</code></th><th>バックティック <code>`</code></th></tr></thead>
<tbody>
<tr><td>仕様上の挙動</td><td>同じ</td><td>同じ</td><td>テンプレートリテラル (拡張)</td></tr>
<tr><td>変数補間 <code>${x}</code></td><td>不可</td><td>不可</td><td>可</td></tr>
<tr><td>複数行</td><td>不可 (改行は <code>\n</code>)</td><td>不可</td><td>可</td></tr>
<tr><td>JSON で使えるか</td><td>不可 (パースエラー)</td><td>必須</td><td>不可</td></tr>
<tr><td>HTML 属性内</td><td><code>attr="..."</code> の中で安全</td><td><code>attr='...'</code> の中で安全</td><td>属性内では不要</td></tr>
<tr><td>慣習 (Airbnb/Standard)</td><td>★ 推奨</td><td>許容</td><td>補間時のみ</td></tr>
<tr><td>慣習 (Prettier 既定)</td><td>★ 既定 <code>singleQuote: true</code> も<br>4.0 までは <code>"</code></td><td>―</td><td>―</td></tr>
</tbody>
</table>

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

<p>変数を埋め込みたい / 複数行を書きたいときは、ES2015+ のバックティック <code>` `</code> を使います。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const name = &apos;Alice&apos;;
const age = 30;

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

// ✅ テンプレートリテラル
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(&apos;|&apos;) + &apos; / &apos; + values.join(&apos;,&apos;);
}
tag`Hi ${name} - ${age}`;</code></pre>
<h2>JSON はダブルクォート固定</h2>

<p>JSON 仕様 (RFC 8259) では文字列もキーも <strong>ダブルクォート必須</strong>。シングルは構文エラーになります。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ✅ 正しい JSON
const ok = &apos;{"name":"Alice","age":30}&apos;;
JSON.parse(ok);          // { name: &apos;Alice&apos;, age: 30 }

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

// JavaScript のオブジェクトリテラルとは別物
const obj = { name: &apos;Alice&apos;, age: 30 };   // ← JS なので OK
const jsonStr = JSON.stringify(obj);
// → &apos;{"name":"Alice","age":30}&apos; (常にダブル)</code></pre>
<h2>HTML 属性に埋め込むときの選び方</h2>

<p>HTML 属性は <code>"..."</code> または <code>'...'</code> どちらでも書けます。<strong>外側と逆のクォートを内側で使う</strong>とエスケープを減らせます。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// ✅ HTML 属性が " なら JS は &apos; に
const html1 = &apos;<a href="https://example.com" onclick="alert(\&apos;hi\&apos;)">link</a>&apos;;
const html2 = `<a href="https://example.com" onclick=&apos;alert("hi")&apos;>link</a>`;

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

// React / JSX
// 属性値は {} で式を渡せばクォート問題は出ない
const Btn = <button onClick={() => alert("hi")}>Go</button>;</code></pre>
<h2>エスケープシーケンスはどちらも同じ</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">const s1 = &apos;line1\nline2\ttab&apos;;
const s2 = "line1\nline2\ttab";
console.log(s1 === s2);   // true

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

// Unicode
const heart = &apos;❤&apos;;      // ❤
const emoji = &apos;\u{1F600}&apos;;   // 😀 (ES2015+)</code></pre>
<h2>ESLint / Prettier での強制</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-json">// .eslintrc.json - シングル強制
{
  "rules": {
    "quotes": ["error", "single", {
      "avoidEscape": true,
      "allowTemplateLiterals": true
    }]
  }
}

// .prettierrc - Prettier (デフォルトは "single": false = ダブル)
{
  "singleQuote": true,
  "jsxSingleQuote": false
}</code></pre>
<p>大事なのは<strong>チーム内で統一</strong>すること。<code>git diff</code> のノイズを減らすために、必ず Lint で自動修正できる状態を作っておきます。</p>

<h2>Python / PHP / Rust との違い</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#fff3e0"><th>言語</th><th>差</th></tr></thead>
<tbody>
<tr><td>JavaScript</td><td>完全等価。バックティックでテンプレ</td></tr>
<tr><td>Python</td><td>完全等価。三重 <code>"""</code> / <code>'''</code> で複数行。f-string <code>f".."</code> で補間</td></tr>
<tr><td>PHP</td><td><strong>違いあり</strong>: <code>".."</code> は <code>$var</code> 補間あり、<code>'..'</code> は無し</td></tr>
<tr><td>Rust / Go / Java</td><td><code>".."</code> は文字列、<code>'..'</code> は <strong>char (1文字)</strong> なので意味が違う</td></tr>
<tr><td>Bash</td><td><code>".."</code> は変数展開あり、<code>'..'</code> は無し (PHP と同じ系)</td></tr>
</tbody>
</table>

<h2>FAQ</h2>

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

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

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