jQuery の時代で取り残されてたので、今風の書き方を勉強した

JavaScript, jQuery

Web の勉強を2012年頃にしたのですが、そこから知識のアップデートをしていなかったので完全に取り残されていました。
たまに担当システムの要件で JS を書くことがあり、その過程で今風な書き方を色々と勉強しました。

一番驚いたのは、2012年当時は「素のJavaScriptで書くのは罰ゲーム」みたいなイメージだったのですが、
そこからかなり進化していて、jQuery などのライブラリがなくても複雑な処理が書けるようになっていることでした。

いくつか印象に残ったことについて、この記事にまとめたいと思います。
なお、今風の書き方を実践すればするほど、IE や Safari では動かなくなります。

要素に値を保持させるには data 属性を使う

data 属性とは

フロントやってる人からしたら「知らなかったの!?」と言われるレベルの常識らしいのですが、最近まで知りませんでした。

data 属性とは data-*="value" の形で任意のデータを要素に持たせることが出来る機能です。
JavaScript でその要素が持っている特定のデータについてなにか処理をしたい、というときに簡単にデータを持たせることが出来るようになりました。
例えば、地方を表す div 要素があったとき、それぞれに天気のデータを持たせるコードは以下のように書けます。

この中で、北海道の天気を取得するJavaScript は以下のように
element.data.(属性名) の形で書けます。

この機能がない時は、class の中に無理矢理データを持たせたりしていたのですが、

クラスの一覧を取得し、その中で weather で始まるクラスを探し、天気の部分だけをパースして…と面倒でした。
そもそも、class はデータを入れるための場所ではないので、この様な使い方は正しくありません。

data-* の属性はいくつでも持たせることが出来るので、なにか要素に付随する状態や属性を表したい場合はこちらを使うべきです。
(逆に、見た目に関するものをこちらに入れるのは正しくありません。classを使いましょう)

値の取得・設定

JavaScript を使ってこれらの値を取得・設定する時には、dataset 関数を使います。

例えば、以下のような HTML に対して値を取得するには、

以下のような JavaScript で可能です

data-* の後は複数の単語を書くことが出来ます

複数の単語が続く場合、dataset ではキャメルケースで記述します

DOM 要素を選択する場合には querySelector() を使う

querySelector を使うと jQuery と同じような書き方で DOM 要素を選択することが出来ます。
querySelectorAll は合致する要素の配列が返ってきます(1つしかなくても配列で返ってきます。
一方、 querySelector は一番最初に合致した要素が返ってきます。
Web の最先端である Google Developers のサンプルコードを見ても、 querySelector/querySelectorAll が沢山出てきます。

一昔前は JavaScript でDOM 要素を選択するには getElementByIdgetElementsByClassName でした。
(クラスで絞り込む場合には複数個返ってくるので Element’s’です。英語って難しいですね)
これらの関数はその名の通り、IDやクラス名から要素を選択するという機能を持っているのですが、
ID やクラス名以上に複雑な選択をしようとすると記述が煩雑になっていました。

例えば、以下のような div があったとき

getElementsByClassName を使って天気が sunny の要素だけを取り出そうとすると、以下のようになります。
要素を選択するだけなのにこんなに書かないといけません。

jQuery ならばこれを CSS セレクタで記述することが出来るので、
非常にシンプルな形で書くことが出来ます(コードは省略)。

querySelector(), querySelectorAll() を使うと、jQuery と同じように簡潔に書くことが出来ます。
さっきは8行だったコードがたったの2行になりました

for 文 は複数の書き方がある

JavaScript はC言語ライクな for 文を書くことが出来ます。
それに加え、今風の言語では当たり前なオブジェクトの中身を取り出す for-each 的な書き方もできます。

例として、引き続き先ほどのHTMLを使用します。

div の配列を用意します。

この配列をいろんな方法で取り出して見ましょう

[方法その1] for (i = 0; i < length; i++)

私が大学で習った for 文はこの書き方でした。

[方法その2] for-in 文

for-in を使うと配列のキーが返ってきます。
(ただ、それ以外にも余計な物が返ってきてしまいます)

これは、 divs 自身の要素に加えて、「配列」から継承されるオブジェクトも全て返ってくるためです。
自分自身の持つ要素だけを取り出したい場合には、 hasOwnProperty を使います。
(IntelliJ 系の IDE の場合、このチェックをしていないと警告が出ます)

最後にこのキーで元の配列にアクセスすると、div 要素にアクセス出来ます。

上記のような仕様により、Mozilla のドキュメントには
配列の繰り返し処理には C 言語ライクな for 文の方が向いていると書かれています。

[方法その3] for-of

注意) IE では動きません

for-of はオブジェクトの値を取り出す事が出来ます。

for-in が Python の object.keys() だとしたら、
for-ofobject.values() にあたります。

ここ数年で追加された仕様のため、古いブラウザでは動かないという欠点がありますが、
とても簡潔に書くことが出来ます。

[方法その4] array.forEach

for-infor-of と違い、これは array 型のオブジェクトにしか使うことが出来ません。

forEach は値の回数だけコールバック関数を実行します。
…と聞いてもよく分からないと思うので、実際にコードで説明します。

このように、コールバック関数の最初の引数に値が入ります。
コールバック関数は引数を3つ持つことが出来ます。

2番目の引数には配列のインデックスが入ります。

3番目の引数には実行中の配列 (この例の場合は divs の値)が入ります。

即ち、 a[i] = v ということになります。


次回予告

  • let
  • template
  • fetch

の3本でお送りいたします。ちなみに、全て IE では動きません

JavaScript, jQuery