始めに
JavaScriptのInput属性を列挙するロジックを書いたときに若干、はまったことを書いてみます
環境
Google Chrome バージョン: 59.0.3071.115(Official Build) (64 ビット)
やりたいこと
<input type='text' id='testid' size='30'/><br>
<input type='text' id='testid2' size='30'/><br>
<input type='hidden' id='testid3' value='test'/>
<input type='button' value='実行' onclick='g()'/>
という入力フィールドがあったとき、
[testid=入力値,testid2=入力値,testid3=入力値・・・・]
というように
"id名=入力値"
という組み合わせの配列をできるだけJavaScriptの組み込み関数のみを使ってやってみたい
やってみたこと
document.getElementsByTagNameとmapを組み合わせてみる
inputタグの一覧を取得するには
document.getElementsByTagName(取得したいタグ名)
ででき、それぞれの要素にアクセスするには
document.getElementsByTagName(取得したいタグ名)[0]
という感じでできることが分かった
ならば、
document.getElementsByTagName(取得したいタグ名)
.map(a=>`${a}=${f(a)}`)
で一発で変換できるんじゃないかと考え、実行してみた
エラーが発生する
実行後、コンソールを見ると「map」というfunctionは存在しないというエラーが発生した
mapは配列の関数として定義されているので、「document.getElementsByTagName」の型が配列ではないのは分かったので、実際の型はなんだ、というわけで、typeofで型を調べたら「Object」が帰ってきた
・・・JavaScriptのObjectは添え字に数字を指定してプロパティにアクセスできることをすっかり忘れていた・・(汗)
Objectのプロパティ一覧とmapとdocument.getElementById属性を組み合わせる
「document.getElementsByTagName」で返ってくる型がObjectだと分かったので、Objectのkey属性の一覧を取得し、その一覧に対して、「map」と「document.getElementById」の組み合わせでやりたいことが実現できそう。
後、Objectのプロパティ一覧には配列のような添え字でアクセスできるようにするためのindexが含まれているので、それらを除外するロジックも併せて書いておく
function g(){
k('input')
.filter(a=>isNaN(a))
.map(a=>`${a}=${f(a)}`)
}
function f(str){
return document.getElementById(str).value;
}
function k(str){
return Object.keys(document.getElementsByTagName(str))
}
関数 g()を実行すると、目的の"id名=入力値"の組み合わせが取得できた
おわりに
JavaScript、配列とObject型の区別が分かりにくいです
配列とオブジェクトを意識的に分けてロジックを書くとき、この変数が今、Object型なのか配列なのかを意識するのは相当面倒くさいです