ネイティブJSのやってみたシリーズ。前回まではアロー関数について掘り下げました。今回は基本に立ち返り、オブジェクトのプロパティの指定の仕方を掘り下げます。CSSみたいに途中を省略した書き方はできるのか?普段なんとなく使ってるけどフワッとしていた部分を明確にしました。それではいきましょう!
【目次】
- CSSは省略した指定ができる
- JSオブジェクトのプロパティ指定テストを作った
- 入れ子階層のオブジェクトを作る
- プロパティの指定方法(全部、省略、途中、中間)
- DOMを取得
- クリックイベントを設定(挙動の検証)
- 最後に
前回記事
※参考:【JS】アロー関数のthisの挙動(プロトタイプとクラスの違い) - クモのようにコツコツと
※参考:ネイティブJSでいろいろやってみたシリーズ
qiita.com
CSSは省略した指定ができる
例えがこんな階層のHTMLがあるとする。
<section> <h1>タイトル</h1> <p>本文です。本文です。本文ですたら本文です。本文です。本文です。本文ですたら本文です。本文です。本文です。本文ですたら本文です。本文です。<b>ここ重要!テストに出るぞ。</b>本文です。本文ですたら本文です。本文です。本文です。本文ですたら本文です。本文です。本文です。本文ですたら本文です。本文です。本文です。本文ですたら本文です。</p> </section>
section
タグの中にp
タグがあり、p
タグの中にb
タグがある。
CSSの指定はわりと自由。
/* 全部指定 */ section p b { color: red; font-weight: bold; } /* 省略指定 */ section b { color: red; font-weight: bold; } /* 単独指定 */ b { color: red; font-weight: bold; }
上記の3つの書き方のどれでもCSSのスタイルはあたる。(ただ、詳細度によって同じスタイルが重複した時の優先順位は変わる)
※参考:【CSSの基本】書ける前に読む!HTML、CSS、JSの書式-3 - クモのようにコツコツと
同じような指定の仕方がJSのオブジェクトでも可能なのか検証したい。
JSオブジェクトのプロパティ指定テストを作った
作ってみたものがこちら。
See the Pen JS Object test_1 by イイダリョウ (@i_ryo) on CodePen.
ボタンを押すとアラートが立ち上げるが、それぞれの表示されるテキストが異なる。
HTMLコード
<div class="btns"> <p>ネストしたオブジェクトを省略して指定できるかテスト</p> <button class="obj">オブジェクト</button> <button class="zenbu">全部指定</button> <button class="shoryaku">省略指定</button> <button class="tochu">途中指定</button> <button class="chukan">中間指定</button> </div>
.btns
の中にボタンがいくつかあり.obj
、. zenbu
、. shoryaku
、. tochu
、.chukan
と言うクラス名をつけている。
JSコード
//オブジェクト設定 const testObj = { aaa: { iii: { uuu: { eee: "ooo" } } } } //プロパティ指定 const objZenbu = testObj.aaa.iii.uuu.eee; const objShoryaku = testObj.eee; const objTochu = testObj.aaa.iii; const objChukan = testObj.iii; //DOM取得 const obj = document.querySelector('.obj'); const zenbu = document.querySelector('.zenbu'); const shoryaku = document.querySelector('.shoryaku'); const tochu = document.querySelector('.tochu'); const chukan = document.querySelector('.chukan'); //クリックイベント obj.addEventListener( 'click', function () { alert( testObj ); }, false ); zenbu.addEventListener( 'click', function () { alert( objZenbu ); }, false ); shoryaku.addEventListener( 'click', function () { alert( objShoryaku ); }, false ); tochu.addEventListener( 'click', function () { alert( objTochu ); }, false ); chukan.addEventListener( 'click', function () { alert( objChukan ); }, false );
- 変数
testObj
でオブジェクトを作っている。入れ子構造になっている - 変数
objZenbu
、変数objShoryaku
、変数objTochu
、変数objChukan
でオブジェクトを指定している - 変数
obj
、変数zenbu
、変数shoryaku
、変数tochu
、変数chukan
でHTML上のDOMを取得 obj
、zenbu
、shoryaku
、tochu
、chukan
のクリックイベントを設定
以下でコードの詳細を見ていく。
入れ子階層のオブジェクトを作る
//オブジェクト設定 const testObj = { aaa: { iii: { uuu: { eee: "ooo" } } } }
- 変数
testObj
の値は連想配列 testObj
の連想配列にはaaa
キーがあり、この値も連想配列aaa
の連想配列にはiii
キーがあり、この値も連想配列iii
の連想配列にはuuu
キーがあり、この値も連想配列uuu
の連想配列にはeee
キーがあり、この値はooo
と言う文字列
testObj
オブジェクト > aaa
プロパティ > iii
プロパティ > uuu
プロパティ > eee
プロパティ > 値ooo
と言う構造になっている。
プロパティの指定方法(全部、省略、途中、中間)
testObj
オブジェクトのプロパティをいろんな指定の仕方で設定してみる。
//プロパティ指定 const objZenbu = testObj.aaa.iii.uuu.eee; const objShoryaku = testObj.eee; const objTochu = testObj.aaa.iii; const objChukan = testObj.iii;
- 変数
objZenbu
ではeee
プロパティを指定するために全てのプロパティを書く(testObj.aaa.iii.uuu.eee
) - 変数
objShoryaku
では途中のプロパティを省略して最後のeee
プロパティを指定(testObj.eee
) - 変数
objTochu
では途中のiii
プロパティまでを書く(testObj.aaa.iii
) - 変数
objChukan
では途中をすっ飛ばして中間にあるiii
のみを書く(testObj.iii
)
前半2つは一番最後のeee
プロパティを指定。objZenbu
は全部書いてobjShoryaku
は途中を省略している。
後半2つは途中のiii
プロパティを指定。objTochu
は途中まで全部書いてobjChukan
は途中を省略している。
DOMを取得
次にHTMLのDOMを取得する。
//DOM取得 const obj = document.querySelector('.obj'); const zenbu = document.querySelector('.zenbu'); const shoryaku = document.querySelector('.shoryaku'); const tochu = document.querySelector('.tochu'); const chukan = document.querySelector('.chukan');
- 変数
obj
で.obj
を取得 - 変数
zenbu
で. zenbu
を取得 - 変数
shoryaku
で. shoryaku
を取得 - 変数
tochu
で. tochu
を取得 - 変数
chukan
で. chukan
を取得
これらのclass名はHTMLのbutton
タグに付けたもの。
クリックイベントを設定(挙動の検証)
最後にクリックイベントを指定している。一つずつ挙動を見ていこう。
オブジェクト自体を指定
まず最初に大元のオブジェクト自体を指定してみる。
obj.addEventListener( 'click', function () { alert( testObj ); }, false );
obj
をクリックするとアラートでtestObj
を表示する
testObj
はオブジェクト自体だ。どんな結果が出るか?
→結果:「[object Object]」と言うアラートが出る。
このobject Object
と言う結果は「obj
の中身はオブジェクトですよー」と言う情報を意味している。
オブジェクトの中身(プロパティなど)の情報までは結果に含まれない。
※参考:JavaScript オブジェクトの基本 - ウェブ開発を学ぶ | MDN
オブジェクトの中身の情報を表示したい場合はJSON.stringify()
で文字列化する方法がある。
obj.addEventListener( 'click', function () { alert( JSON.stringify(testObj) ); }, false );
このようにJSON.stringify()
の引数にtestObj
を入れたところ中身が表示された!
→結果:「`{"aaa":{"iii":{"uuu":{"eee":"ooo"}}}}`」と言うアラートが出る。
また、コンソールに表示する場合はconsole.dir()
にしてもいいようだ。
※参考:console.logでJSON形式の値が[object Object]になる時 - Qiita
プロパティを全部指定
zenbu.addEventListener( 'click', function () { alert( objZenbu ); }, false );
zenbu
をクリックするとアラートでobjZenbu
を表示する
objZenbu
の中身はtestObj.aaa.iii.uuu.eee
で、eee
に至るまでの全てのプロパティを書いている。
→結果:「ooo」と言うアラートが出る。
これは期待通りの結果!まあ全部書いているから当然こうなる。
これを省略した書き方ができるのかを検証したい。
プロパティを省略指定
shoryaku.addEventListener( 'click', function () { alert( objShoryaku ); }, false );
shoryaku
をクリックするとアラートでobjShoryaku
を表示する
objShoryaku
の中身はtestObj.eee
で、aaa
プロパティ、iii
プロパティ、uuu
プロパティを省略している。
→結果:「undefined」と言うアラートが出る。
「undefined」は「定義されてないよ!」と言う意味。
※参考:nullとundefined | JavaScript中級編 - ウェブプログラミングポータル
定義自体はしているんだが、階層的にはtestObj
オブジェクトの直下にeee
プロパティを定義しているわけではないため「eee
なんて見つからないよ!」と言う結果になったんだろうな。
やはりJSのオブジェクトのプロパティ指定は厳密っぽいことがわかる。
プロパティを途中まで指定
次、プロパティを途中まで指定してみた。
tochu.addEventListener( 'click', function () { alert( objTochu ); }, false );
tochu
をクリックするとアラートでobjTochu
を表示する
objTochu
の中身はtestObj.aaa.iii
と途中の改装までになっている。
→結果:「[object Object]」と言うアラートが出る。
これは最初のtestObj
と同じ結果。iii
プロパティの値を見に行ったらuuu
自体も連想配列(オブジェクト)なわけなので「オブジェクトがあるよー」と言う事になる。
ちょっとややこしいがJSは値に関数でも変数でも配列でも連想配列でもなんでも入れられるからこうなる。
プロパティの中間を指定
chukan.addEventListener( 'click', function () { alert( objChukan ); }, false );
chukan
をクリックするとアラートでobjChukan
を表示する
objChukan
の中身はtestObj.iiiで、
iiiプロパティを指定するにあたり途中の
aaa`プロパテいを省略している。
→結果:「undefined」と言うアラートが出る。
これはobjShoryaku
と同じ結果。testObj
の直下のプロパティを見に行って「iii
なんてプロパティは見つからないよー」と言う結果を返している。
最後に
See the Pen JS Object test_1 by イイダリョウ (@i_ryo) on CodePen.
と言うことでプロパティ指定の検証結果はこうなりました。
項目 | 指定方法 | 結果 |
---|---|---|
オブジェクト自体を指定 | testObj | [object Object] |
プロパティを全部指定 | testObj.aaa.iii.uuu.eee | ooo |
プロパティを省略指定 | testObj.eee | undefined |
プロパティを途中まで指定 | testObj.aaa.iii | [object Object] |
プロパティの中間を指定 | testObj.iii | undefined |
わかったこと
- オブジェクトを指定すると
object Object
になる - プロパティを指定すると直下の値のみを見る(入れ子階層の場合、さらに下の階層は見てくれない)
- プロパティの値が文字列の場合は文字列が返ってくる
- プロパティの値が連想配列(オブジェクト)の場合も
object Object
になる - プロパティの上の階層を省略して書くと
undefined
になる
JSのプロパティは直下の値しか見に行ってくれないので、CSSのように省略した書き方はできないことがわかりました。オブジェクトの階層自体もあまり深くしない方が指定しやすそうですね。それではまた!
※参考:ネイティブJSでいろいろやってみたシリーズ
qiita.com