JavaScriptではオブジェクトのプロパティにアクセルする際、ドット記法とブラケット記法という方法があります。例えばユーザーエージェントの取得は『navigator.userAgent』とドット記法で記述することが多いですが、これは『navigator[‘userAgent’]』と記述することもできます。ようは、配列のような書き方です。
このブラケット記法の利点として、ドット記法では表せないプロパティ名でもアクセスできるというメリットがあります。例えば以下の様なオブジェクトがある場合、
var obj = {
'test' : 'テスト',
'am-yu' : 'あみゅ',
1 : 'いち',
'10px' : "じゅっピクセル",
'if' : 'イフ',
true : 'トゥルー'
}
ドット記法やブラケット記法でのアクセスは下記のようになります。
// ドット記法
console.log( obj.test ); //=> "テスト"
//console.log( obj.am-yu ); // エラー
//console.log( obj.1 ); // エラー
//console.log( obj.10px ); // エラー
console.log( obj.if ); //=> "イフ"
console.log( obj.true ); //=> "トゥルー"
// ブラケット記法
console.log( obj['test'] ); //=> "テスト"
console.log( obj['am-yu'] ); //=> "あみゅ"
console.log( obj[1] ); //=> "いち"
console.log( obj['1'] ); //=> "いち"
console.log( obj['10px']); //=> "じゅっピクセル"
console.log( obj['if'] ); //=> "イフ"
console.log( obj['true'] ); // "トゥルー"
console.log( obj[true] ); // "トゥルー"
//=>より右がコンソールに出力される結果です。『am-yu』や『1』や『10px』はドット記法ではエラーとなりますが、ブラケット記法だとアクセスできました。これは、ドット記法の『am-yu』の『-』がマイナスの演算子だと思われてしまったためです。対してブラケット記法だと’am-yu’の文字列として扱うのでエラーになりませんでした。『1』や『10pz』はそもそも数値ではじまるのがダメなようです。ブラケット記法では『1』については文字列ではなく、数値でもアクセスできるのが分かります。ちなみに、普通の配列でも文字列型の数値をいれてもアクセスできます。
var arr = Array();
arr.push(100);
console.log(arr[0]); //=> 100
console.log(arr['0']); //=> 100
実は言うと『if』や『true』などの予約語はドット記法でエラーになるかと思ったのですが、なりませんでした(調べてみると、エラーになると書かれてるところばかりなのだけど、最新のブラウザではエラーにならないということなのだろうか)。しかも、ブラケット記法では『true』は文字列の’true’でも真偽値のtrueでもどちらでもアクセスできました。これはちょっと意外でした。なぜなら厳密でない比較演算子(==)を使うと、数値の場合、『1==’1’』とすれば結果はtrueとなりますが、『true==’true’』の結果はfalseになるからです。
ちなみに、ブラケット記法のカッコ内は式として扱うので、下記のようなこともできます。
var width = 10;
console.log( obj[ width + 'px'] ); //=> "じゅっピクセル"
obj.false = 'ファルス';
console.log( obj[ 1 < 2 ] ); //=> "トゥルー"
console.log( obj[ 1 > 2 ] ); //=> "ファルス"
trueとfalseのプロパティについては工夫次第で面白い使い方ができそうな気もします。
なお、「falseが『ファルス』だってwww。英語も読めないのかよ、『フォールス』だろwww」というツッコミはうけておりません(参考:UDCblog: 今さら人には聞けない「false」「null」の読み方)。
2014/08/17追記:nullやundefinedやNaNもやってみた
obj = {
null : 'ヌル',
undefined : 'アンデファインド',
NaN : 'ナン'
}
// ドット記法
console.log(obj.null); //=> "ヌル"
console.log(obj.undefined); //=> "アンデファインド"
console.log(obj.NaN); //=> "ナン"
// ブラケット記法
console.log( obj[null] ); //=> "ヌル"
console.log( obj[undefined] ); //=> "アンデファインド"
console.log( obj[NaN] ); //=> "ナン"
// ブラケット記法-計算式
console.log( obj[document.getElementById('nothingID')] ); //=> "ヌル"
var x;
console.log( obj[x] ); //=> "アンデファインド"
console.log( obj['string' - 0] ); //=> "ナン"
コメント
ES5以降であれば、メンバ名として予約語が直接使えます。
ブラケット記法の場合はSymbol型以外のものは文字列化されるので、trueは”true”になります。
==での比較の場合は文字列型ではなく数値型へ積極的に型変換されます。
よってtrue==’true’は1==NaNとなりfalseになります。
詳しい解説ありがとうございます。勉強になりました。
やっぱり、昔は予約語をメンバ名に使えなかったんですね。
まだまだJavaScriptは知らないことばかりだということが分かりました。