document.querySelector("div").getAttribute("id")
は「\hoge」という文字列を取得します。これは言うまでもなく、idの値が「\hoge」だからです。同様にdocument.querySelector("div").id
でも「\hoge」が得られます。
次に、JavaScriptのコード上の "\hoge"
から 「hoge」という文字列が得られる理由ですが、ご認識のとおり、 \
は次に続く文字を特殊な文字にするためのキーワードだからです。
たとえば "r"
は特殊じゃないただの「r」ですが、 "\r"
は特殊文字 CR (Carrige Return)
を表しますね。 r
の通常効果はただの「r」、特殊効果が CR
という感じです。
では \
自身はどうでしょうか。この文字は、通常効果が「次の文字を特殊にする」で、特殊効果が「次の文字を特殊にするのをやめて、ただの『\』になる」です。
"\r"
を例に見ると、次のようになります
- 1文字目の
\
... 次の文字を特殊にする
- 2文字目の
\
... 特殊効果で、ただの「\」になった (1文字目のおかげで、次のrを特殊な文字にする効果を失った)
- 3文字目の
r
... 通常効果で、ただの「r」
となり、結果としてただの「\」とただの「r」が連なっただけの「\r」が得られます。
"\hoge"
に話を戻しますが、上の例にならうとこんな感じです。
\
... 次の文字を特殊にする
h
... 特殊効果を持たないので、ただの「h」が得られる
o
... ただの「o」
g
... ただの「g」
e
... ただの「e」
結果として、「hoge」が得られます。
<div id="\hoge"></div>
の \hoge
がエスケープされない理由ですが、HTMLには「\
は次の文字を特殊にする文字である」というようなルールがないからです。
コメントを受けて追記 Sep 17, 2019 9:37 pm
「"\hoge"という文字列をJSで取得すると"\hoge"と解釈されるようになる」という理解でよろしいでしょうか?
これは衝撃の事実なのですが、「文字列」と「文字列リテラル」は別物です。私の回答は意図的に、文字列はカギカッコ、文字列リテラルはダブルクォートで囲って示しています。
「\hoge」という文字列を取得する方法はいくらでもあります。下記の例はいずれも「\hoge」という文字列を取得してコンソールに表示するコードです。
html
1<div id="piyo" data-fuga="\hoge"></div>
2<script>
3
4// 例1
5const ex1 = document.getElementById('piyo').dataset.fuga;
6console.log(ex1);
7
8// 例2
9const ex2 = [92, 104, 111, 103, 101].map(c => String.fromCharCode(c)).join('');
10console.log(ex2);
11
12// 例3
13const ex3 = '\hoge';
14console.log(ex3);
15
16</script>
例1は、疑問と提示されたのと同様ですね。IDに入れるのは不適とのyoorwmさんのアドバイスを受けて、datasetに変えています。yoorwmさん、ありがとうございます。
例2は、文字コードから文字列を生成する String.fromCharCode()
メソッドを使って、結果を連結しています。
例3は、文字列リテラルから文字列を生成しています。
「文字列リテラル」は文字列を生成するための記法であって文字列そのものではありません。例1と例2はそれぞれの結果として文字列を生成しているのであって、文字列リテラル "\hoge"
に変換されているわけではありません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/17 01:20
2019/09/17 11:59
2019/09/17 12:08