jQueryの次にJavaScriptを学びはじめたキミのための記事！



#記事の目的
この記事は、プログラミング初学者の中でも、
HTML → CSS → jQuery と学んできて、次のステップとしてJavaScriptを学び始めた人が、
技術的な話の前に知っておいたほうが助かりそうな事情や背景をまとめた記事です。

JavaScriptをちょっと初めてみたけど、よくわからん！と混乱しているタイミングで、読んでいただけたらと思います。

「そんなことわかってるよ」と言いたくなるような初歩的な説明もあると思うので、読み飛ばしていただければと思います。

執筆者もプログラミング歴１年程度の初心者なので、知識の浅い部分があります。
また、初心者ながらJavaScriptを学んでしばらくたっているので、当事者目線からずれた説明をしてしまう部分もあるかもしれません。
そのため、この記事のコメント欄で、ターゲットとなる当事者の方や、執筆者よりも博識な方などから、
いろいろな意見を頂きながら成長していくコミュニティにしたいと思っていますので、ご協力よろしくおねがいします！

#jQueryの立ち位置
そもそも、HTML、CSS、jQuery、JavaScriptというのは、何が違くて、どういう風に活躍する言語たちなんでしょうか。

###HTML･CSSの立ち位置
**HTML**は、WEBサイトの構成を表すための言語です。
`<head>`では主に、WEBサイトの構成に必要な設定の記述や、ファイルの読み込みを行い、
`<body>`では主に、どんな構成で要素を配置していくかを表します。

**CSS**は、WEBサイトのデザインを表すための言語です。
HTMLで配置した要素を、どんなデザインでユーザーに見せたいか記述します。

この２つは、jQueryやJavaScriptと違ってプログラミング言語ではありません。
プログラムというのは、機能的な処理をするものの事ですが、
この２つは書いたとおりに表現をしてくれるものですので、**マークアップ言語**と呼ばれ、違うものとして考えるのが一般的です。

ただし近年では、HTMLやCSSだけでもある程度機能的な部分を実装できるようになりつつあります。
例えば、HTMLだけで入力欄入力された文字のチェックをすることも出来ますし[ ※ ](http://html5.cyberlab.info/elements/forms/input-pattern.html)、 
CSSだけでハンバーガーメニューの実装をすることなど出来ますね[ ※ ](https://saruwakakun.com/html-css/reference/nav-drawer)。

このように、HTMLやCSSだけで出来ることについて深く知ることは、
過度にJavaScriptやjQueryへ依存してしまわないためには必要なので、
どんどん情報収集した方がよいと思います。

###JavaScriptの立ち位置
**JavaScript**は、WEBサイト上（＝ブラウザ上）で動かすことができる**プログラミング言語**です。
プログラミング言語って、つまりどんな事ができるの？という話をしだすとキリがないのですが、
要は、**HTMLとCSSだけでは出来ない事は、全てプログラミングで実装している**と理解していればオッケーです。
そして、そのように何でもできる技術だからこそ、何でもできるようになるためには、沢山の知識が必要になります。
（ブラウザ上で動くJavaScriptの他にも、サーバー上で動く**サーバーサイドのプログラミング言語**も存在するので、
　全てJavaScriptという訳ではないのですが、それはもう少し先のお話になります。）

###jQueryの立ち位置
**jQuery**は「JavaScriptでWEBサイトの見た目や動き方を指定したいけど、あまり深い知識まで学んでいられない人」とか、
「できるだけわかりやすく書きたい人」とか、「パパっと仕上げたい人」のために作られた仕組みです。
**HTMLとCSSだけでは出来ない事を、簡単に実装したい**人のための仕組み、と考えてもいいです。

実は、見た目や動き方だけではなく、もっと機能的な処理も簡単に実装できるようにと作られている機能もありますが、
本記事を読みたいと思う方で、そういうところまで使いこなしている方は少ないと思うので、深くは触れません。

#jQueryって何なんだっけ？
jQueryとはどういうものか、についての説明です。
jQueryを学んだ際にも同じような話を聞いたかと思いますが、再び思い出してみて、より深く理解しましょう。

###jQueryは、JavaScriptのライブラリ
jQueryは、JavaScriptの**ライブラリ**です。
ライブラリとは、まとまった機能を切り出して、再利用できる形に保存してあるコードのことです。

CSSで例えるならば

```css:ライブラリ.css
.button{
    borde: 1px solid black;
    border-radius: 5px;
}
```
という内容のファイルを作成して、これをHTMLの`<link>`タグで読み込んで、
このデザインを適用したいボタンに`class="button"`と指定してあげれば、
いつでもボタンを同じデザインに統一することができますよね。
JavaScriptで、これと同じような事をしたものが**ライブラリ**です。

つまり…

###jQueryでやっている事は、JavaScriptでやっている。
**jQueryはJavaScriptのライブラリ**という言葉の真意は、
jQueryの中身はJavaScriptで書かれているということであり、
jQueryでやっている事は、JavaScriptでやっている。
という事になります。

###jQueryの中でJavaScriptも使える。
違う言い方をすると
jQueryの中でJavaScriptをバリバリ使ったプログラムを書いていくことも可能ということです。
というよりも、なんなら既にバリバリ使っていると思います。
簡単なところで言うと`var`や`let`を使った変数宣言や、`=`を使った変数への代入、
`for`や`forEach`などを使ったループ処理、`if`をつかった条件分岐などもそうですね。
jQueryのメソッドではない部分の処理は、すべてJavaScriptの処理だということです。

そうは言っても、jQueryとJavaScriptが同じ書き方には見えない、という方も居るかもしれませんね。

###jQueryの独特な書き方について
jQueryが本来のJavaScriptと違った書き方をしているように見えるなら、それはjQueryが以下の仕組みを積極的に使用しているからだと思います。

1. **「\$」という名付け**
1. **メソッドチェーン**
1. **コールバック関数**

これらの詳しいところは、JavaScriptについて分かってきた後に、やっと理解できるようなレベルの話だったりしますが、
現時点で知っておいた方がいい要点だけ、説明させていただきます。
（わりと長い説明になってしまうので、理解できなければ飛ばしても構いません。）

####「$」という名付け
jQueryの使用を開始するために使う`$( function() { ...`という書き方や、
jQueryでHTMLの要素を操作するために使用する`$('セレクタ')`という書き方など、
jQueryを使用する場合では頻繁に目にする**「\$」**という文字があります。
（`$()`ではなく`jQuery()`と書くことでもjQueryを使う事ができるので、
　そちらの書き方のイメージが強い方であれば、飛ばしていただいて構いません。）

この**「\$」**はjQuery独特の書き方に感じるかもしれませんね。
しかし、JavaScriptのプログラムにおいて**「\$」**という文字に特別な意味はないという事を覚えといてください。
「a」「b」「c」と同じように、普通に使えるただの文字です。

そうは言っても、人間から見れば特殊な文字なので、
大半のプログラマーは、特別な理由がない限り**「\$」**という文字を名前に使うことはありません。

**jQueryを使っている**という、特別な理由がある場合じゃないと使わないような文字なので、
かなり独特に見えるとおもいますが、要はただの変わった名前で**キラキラネームみたいなもの**です。

####メソッドチェーン
`$('ooo').hide()`や`$('xxx').val()`のように、処理を続けて書くような書き方をメソッドチェーンと呼びますが、
これもJavaScriptの学び始めではなかなか見かけないかもしれません。
しかし紐解いて分析してみると、なんてことのないJavaScriptの標準的な使い方だと気づくことが出来ます。

JavaScriptには**オブジェクト型**というデータ型がありますね。複数のデータをまとめて保管できる便利なデータ型です。
（学習環境によっては**連想配列**だとか**Objectオブジェクト**という呼び方で学んだ人もいるかもしれませんが、どれも同じものを指しています。）

オブジェクト型のデータが持っている中身のデータから、あなたが選んだ一つのデータ（＝任意のキーの値）を取り出したい場合、
`オブジェクト.データ`のように、`.`で区切って記述します。
（本来、**オブジェクト**というのは、もっと色んなものを指す言葉なので、そこは誤解されないよう注意してください。）
そして、この`データ`に入る値が、文字列や数値などではなく関数だった場合、
実行するには`オブジェクト.データ()` と書きます。

そうです。jQueryで使われる`$('引数')`がオブジェクトなら、
`$('引数').データ`で、中身の関数を実行することができるのです。

え？
`$()`はオブジェクトじゃなくて関数だろうって？
鋭いですね。

次に必要になる知識が**関数の戻り値（返り値）**という概念です。
関数を実行すると、関数の中で設定した戻り値（＝`return`の値）が、その関数の位置に置き換わります。
（JavaScriptの学びはじめだと`return`は処理を終了させるための記述だと教えられる人もいるかもしれませんが、
　それはあくまで副作用です。本来は、戻り値を指定することが目的の記述になります。）

では、`$`という名前の関数を作って、戻り値に`show`という名前の**関数が入っているオブジェクト**にした場合は…？
そう、`$().show();`と書いてあげることで、`$()`の戻り値に入っている`show`という関数データが実行される事になります。

では、`$()`という関数に、**引数**を渡してあげると…

```JavaScript
$('引数').show();
```

なんということでしょう。
一見、見慣れないプログラミング言語かのようだったJavaScriptが、
匠の手によって、jQueryと同じような記述に生まれ変わりました。

jQueryは、引数として渡された文字列（セレクタ）を、いい感じに処理した上で、
jQueryメソッドと呼ばれる関数を持っているオブジェクトを戻り値にしてくれているんだと、
なんとなくイメージできたでしょうか？
（ちなみに、**メソッド**というのは、オブジェクトや関数などの、何かの中に入ってる関数という意味です。）

jQueryが、きちんとJavaScriptで出来ていることがわかってきたかと思います。

####コールバック関数
最後に説明するのは、
jQueryをはじめる際に現れる
`$( function(){ ...` という書き方についてです。

これは**コールバック関数**と呼ばれる使い方で、調べると結構ややこしい情報がでてきたりしますが
今回の説明に限っていえば簡単なことです。

JavaScriptは、基本的には上から順番に処理を実行してくれるので、
関数の中の、特定のタイミングで別の処理を実行させたい場合の書き方は、下のようになります。

```javascript
function(){
  //事前の処理
  ooo();
  //事後の処理
}
```
しかしこの書き方には、この関数を定義するよりも前に`ooo()`を定義しておかなければならないという弱点があります。
それを回避するために、**引数**に関数を渡すという策があります。

```javascript
function( xxx ){
  //事前の処理
  xxx();
  //事後の処理
}
```
こうする事で、引数に渡された関数が、jQueryの都合のいいタイミングで実行されてくれるのです。
つまり、`$()`の引数に、関数を渡しているのが、`$( function(){ ...`の正体だということです。

####まとめ
ちょっと長い説明になってしまいましたが、結局何が言いたいかというと、
jQueryは、JavaScript学び始めの段階ではまだまだ使い慣れていない仕組みを積極的に使用しているせいで、
なんだかJavaScriptとは違う書き方をしているように見える事があると思いますが、
全てJavaScriptでも使われる書き方だと言うことです。

#jQueryが皆に愛された理由
次は「とりあえずjQuery」と言われるほどに、
jQueryが皆から愛された理由について説明します。
これは、次の章にも関連する内容になります。

###ブラウザ間の動作の違い
JavaScriptは**ブラウザ用のプログラミング言語**です。
**ブラウザ**とは**InternetExplorer**や**Edge**、**Safari**、**GoogleChrome**、**Firefox**などのインターネットを見るためのアプリですが、
これらのアプリの中身は別々の人達が作っているのでJavaScriptはブラウザごとに細かい動作の違いがありました。
（ブラウザ用の言語でなくても、**Windows**や**Mac**などのOSによって動作が違う言語はあるようなので、JavaScript特有の問題というわけではないかもしれませんが。）

「細かい動作の違い」と言いましたが、jQueryが流行った当時は、無視できないくらい大きな違いだったそうです。
単純な処理を実行したいだけなのに、ブラウザの数だけ条件分岐した処理を書かなければいけないとしたらどうでしょう？
趣味でやるなら「頑張れ〜！」で済む話かもしれませんが、仕事であれば時間に対して給料が発生していますので、
小さな処理でも何か書く度に何パターンも考えなければいけないなんて、たまったものじゃありませんね。

それをjQueryは、あらかじめそれぞれのブラウザで狙った処理になるようにまとめてくれているそうです。

###以前のJavaScriptは、今より不便だった。
JavaScriptを最近学びはじめた人であっても「ES5」と「ES6」のバージョンの違いがあることはご存知かと思うので、
想像に容易いかと思いますが、
JavaScriptは日々進化し続けています。

それは裏を返すと、少し前の時代のJavaScriptはものすごく不便だったということです。
JavaScriptを駆使する「フロントエンドエンジニア」という職種も最近現れた職種だということからわかるように、
以前はJavaScriptで色々やるなんて想像もできなかったというか、
そこまでのパワーは無かったものだと思います。

#jQueryから皆が離れはじめた理由
前章を受けて、そんなに愛されたjQueryから、なぜ人々が離れ始めてしまったのかについて説明します。
###ファイルサイズの肥大化
JavaScriptと同じように、jQueryも時代とともに進化しています。
JavaScriptは元々ブラウザに組み込まれているものですが、
jQueryは**ライブラリ**という一つのファイルですので、
jQueryが進化するということは、jQueryのファイルサイズが肥大化するということです。
サイトで読み込むファイルのサイズが肥大化するということは、
サイトを表示するスピードが遅くなるということです。

読み込むだけで30秒とか1分とか遅くなるっていうことはないのですが、
jQueryの処理ひとつひとつもそんなに処理速度が早いわけでは無いようで、
jQueryの読込と処理の遅さに加えて、
低スペックスマホや通信速度の遅いフリーWi-Fiなどの環境問題、
さらにGoogleがページ表示速度の高速化を推奨しているなど、
いろんな要素が合わさることによって、ページの表示速度がかなり気にされる要素となってきています。


###InternetExplorer離れ
先程の章で**ブラウザ間の動作の違い**について説明しましたが、
最近学びはじめた方からすると「そんなに違うか？」と思われたかもしれません。
これはなぜかというと、
ブラウザ間で最も動作が違っていたのが、**InternetExplorer**だからです。
今となってはWindowsの標準ブラウザは**Edge**に変わったので、ほとんどの人は使っていないかと思います。

このInternetExplorerはCSSでも色々面倒な問題を起こしてくれていたブラウザですが、
同じようにJavaScriptにおいても、色々面倒な存在だったみたいです。

そのInternetExplorerが主要ブラウザの座から引退してくれたおかげで、
InternetExplorerの動作の違いを解決するためにやっていた色々なことが不要になり、たくさんのエンジニアが救われたそうです。
ただ、そうなると、その問題の解決をしたくて流行っていたjQueryは、必要のない処理が沢山記述されている重いライブラリ、という立ち位置になってしまうわけですね。
世知辛い世の中です…。


###DOM操作系の充実
先程の章で**以前のJavaScriptは、今より不便だった。**と説明しましたが、
その最たるものが、皆様がjQueryで一番よく使われていると思われる**DOM操作**についての機能です。

**DOM操作**というのは、JavaScriptでHTMLの要素をいじったり、値を取得したりする処理のことです。
（HTMLをJavaScriptで扱えるデータに変換したものを**DOM**と呼ぶのですが、
　難しければ「DOMというのはHTMLのことだ」と思っていても問題ないかと思います。）

これ、jQueryじゃないと出来ないと思っていませんでしたか？
これは余談になるのですが、筆者が使っていた、とある学習サービスでは、
JavaScriptのレッスン中にDOM操作の方法を教えてくれるレッスンが存在していなくて、
最初はJavaScriptを学んでも「だから何？」という状態がしばらく続いていました。
jQueryを学ぶことで、はじめて「あ、これをうまく使えばサイトをいい感じに動かせるんだな」と理解したのです。
そのサービス自体は愛用させていただいてるので名前は伏せますが、同じサービスを使って勉強されている方は、
JavaScriptでDOM操作ができるという事実を知らないかもしれませんね…。

おっと、話が脱線しました。
以前のJavaScriptは、今より不便だったと言いましたが、
特に衝撃だったのが`document.querySelectorAll()`という関数の誕生だと思います。
（おそらくjQueryをリスペクトして作られた関数ではないかと予想します。）
「JavaScript　DOM操作」とググっていただければ色々な記事がヒットするのでサラッとしか説明しませんが、
この関数の引数に、jQueryの`$()`と同じようにセレクタを指定してあげることで、指定した要素の**DOM**が取得できる関数です。

あとは、取得したDOMのプロパティを取得したり書き換えたりすれば、HTMLに関する処理はできちゃうというわけですね。
ぶっちゃけ、この**DOM操作**を普通に扱えるようになれば、
大体のアプリはjQueryを使わずに作成することができますし、
それが出来るようになれば「なんでjQuery使ってたんだっけ？」とも思うようになります。笑

###仮想DOM操作ライブラリの誕生
と、ここまでjQuery離れをしている理由をいろいろ挙げてみましたが、実はこちらが大本命です。
この理由に該当しない案件であれば、まだまだjQueryが現役で使われまくっている事も珍しくはないです。

jQueryや、ライブラリを使わないJavaScript（＝バニラJS）でDOM操作をする場合、
当然、なにかデータを書き換えたらHTMLに反映、という処理を繰り返しています。
細かく言うと、JavaScriptで１つ処理をする→HTMLに反映する→JavaScriptで１つ処理をする…という処理を延々繰り返しています。


しかし、近年現れた**Angular**、**React**、**Vue.js**、**Hyperapp**などのライブラリは、
**仮想DOM**という仕組みを利用しており、JavaScriptの処理をまとめてする→HTMLに反映するという処理になっています。
これによって、もちろん処理速度が向上するといった裏側のメリットももちろんあるのですが、
**仮想DOMで操作している最中に通常のDOM操作をしてしまうと、処理がおかしなことになる危険性**を孕んでいます。

もちろん、HTMLに処理を反映しないような処理（テキストの取得など）であればjQueryを使用しても問題はないですが、
その程度の処理であればバニラJSのDOM操作で十分対応できますし、
上記ライブラリたちの特徴である**データバインディング**（JavaScriptのデータとHTMLの内容をリンクしてくれる機能）のおかげで、そもそもDOMを操作する必要すらない場面も増えました。

（さきほどから仮想DOM操作の**ライブラリ**と言っていますが、正確には一部は**フレームワーク**と呼ばれています。
　この２つはJavaScriptにおいては規模感が違うだけなので、今は意識しなくて大丈夫です。）

#実際に置き換えてみる
さて、ここまでjQueryを使う理由、使わない理由、JavaScriptとの違いなどの話をしてみましたが、
最後は実践的にjQueryをJavaScriptに置き換えて使ってみたいと思います。
これをマスターすれば、jQueryを使わなくても簡単にいろんな事が出来るようになりますよ！

###エレメントを取得する
**エレメント**というのは、実際に取得した**DOM**ひとつひとつのデータのことです。
####document.querySelector系の関数
**querySelector系**の引数には、jQueryと同じように、CSSセレクタと同じ形の文字列を渡します。
#####`document.querySelector();`
セレクタにヒットするHTML要素がいくつあっても、最初の１つだけ取得します。
基本的には、１つしかヒットしないはずのものを取得したい時に使います。
例: `document.querySelector('body');` `document.querySelector('#id');`

#####`document.querySelectorAll();`
セレクタにヒットするHTML要素が入っている**配列のようなもの**を取得します。
注意点として、要素がひとつしかなかったとしても、取得するのは**配列のようなもの**なので、
実際にHTMLの処理をしたいときは、取得したデータの**中身**にアクセスして処理する必要があります。
例: `document.querySelectorAll('div');` `document.querySelectorAll('.class');`

####document.getElement系の関数
**document.getElement系**の関数は、id属性やclass属性など、HTMLのどの属性から探して取得してくるかは予め決まっているので、
引数としては**文字の部分のみ**を渡します。

#####`document.getElementById();`
指定した文字列と一致するid属性を持っている要素を取得します。
idは固有のものにするというルールがあるため、関数名は**getElement**と単数形になっています。
例: `document.getElementById('id');` `document.getElementById('menu');`

#####`document.getElementsByClassName();`
指定した文字列と一致するclass属性を持っている要素が入っている**配列のようなもの**を取得します。
classをはじめとする、id以外のものは複数ヒットする可能性があるため、関数名は**getElements**と複数形になっています。
例: `document.getElementsByClassName('class');` `document.getElementsByClassName('icon');`

類似する関数に、name属性の値で取得する`getElementsByName`や、
HTMLタグの名前で取得する`getElementsByTagName`もあります。

#####「配列のようなもの」について
先程がら太字にしている**配列のようなもの**についてですが、なぜこのような言い方をしているかというと、
実際に**配列**と言っていいのは**配列型**のデータのみだからです。
（学習環境によっては**Arrayオブジェクト**という呼び方で学んだ人もいるかもしれませんが、同じものを指しています。）

複数のデータが入っているとか、`[]`を使って任意のindex番号にアクセスできるところは配列と同じなのですが、
配列では使えるような、特有の関数が使えなかったりします。

また、**querySelectorAll**と**getElements系の関数**では
取得してくる**配列のようなもの**の正体が違います。
querySelectorAll が取得してくる配列には**NodeList**という名前がつけられており、
getElements系 が取得してくる配列には**HTMLCollection**という名前がつけられています。

この２つの違いについて調べると、HTMLCollectionは中身のデータがHTMLと連動しており、
NodeListは中身のデータは取得した時点で内容が固定されているという話が出てきますが、
こちらの環境でテストしてみたところ、NodeListの中身も、しっかりとHTMLと連動していたので、
最近は改善されたのか、もしくは実行環境によって動作が違うのかもしれません。


###DOM操作してみる
お疲れさまでした。おもったより長文になってしまいました。
ここまで読み切ったあなたは、立派なJavaScript入門者です！

つぎは、実際にDOM操作してみましょう。
プログラミング言語を学ぶ上で大事なのは、実践です。

ブラウザの検証ツールの**console**から、DOM操作系の処理を試してみてください。
この記事でできることの一例を挙げてみようと思ったのですが、出来ることが多すぎるので、ぜひGoogle先生に聞いてみてください。
プログラミング言語を使う上で大事なのは、検索です。笑

「JavaScript　DOM操作」や「JavaScript　DOM操作　やりたいこと」などで検索したら沢山ヒットするかと思いますが、
最終的に全てが載っているのは[MDNのドキュメント](https://developer.mozilla.org/ja/docs/Web/API/Element)になります。