JavaScript

CGIJavaScriptの違い

CGIでは、サーバー側でプログラムを実行し、その結果をブラウザに表示して、そこからサーバー側にリクエストを行う際でも、常にサーバー側(サーバーサイド)でプログラムが実行される。
だが、JavaScriptは、HTMLのデータを受け取ってきた後で、ブラウザ側(クライアントサイド)でプログラムを実行する。
JavaScriptでは、掲示板やSNSのようなプログラムではなく、グラフィックスやAjaxなどの技術を用いて、「豪華な見た目のWebサイト」を作ることができる。

JavaJavaScriptは別物

JavaJavaScriptは、同じ「Java」という名前を冠していますが、両者は別物です。
元々JavaScriptNetscapeによってブラウザ上でライブに実行されるスクリプトとして作られたもので、当初はLiveScriptという名前が付けられていましたが、当時Javaを開発していた会社であるSunとの業務提携により、Javaという名前をつけてJavaScriptという名称になりました。
今ではNetscapeという会社は無くなり、後継のオープンソースWebブラウザの開発元はMozilla.orgになりましたし、ECMAという標準化団体によってECMAScriptというJavaScriptの標準が定められていますが、Javaとは全く別の言語です。

最先端技術が多い

JavaScriptには、Webの最先端技術が多いです。特に、jQueryやNode.jsやVue.jsやReactが広く使われており、最近では必ずしも「機能が貧弱」であるとは言えず、むしろ「さまざまなAPIを使ってさまざまな高度なやり方ができる言語」になりました。
JavaScriptと一言に言っても、どの技術を利用するかによって、記述される言語要素や概念が全く違うのです。
JavaScriptは、最先端のWeb技術を学びたい「ギーク」には面白いでしょうが、一般のエンジニアにとっては、「今まで学んだJavaScriptの技術がもう古いものになっている」という状況になりかねません。
よって、一部のJavaScriptオタクの間で(特にQiitaなどで)さまざまな技術知識を共有するだけで、実際の開発には実績がなく使えない、ということも多いです。
ですが、もともとのJavaScriptは単純で、ホームページの作成などに使える、Webブラウザという名前の言語処理系が一番広く広まっている言語であり、また今一番熱い言語であると言えます。基本を知っておくことは無駄にはなりませんし、GoogleFacebookなどの「超最先端企業」に勤めたいとか、最先端の研究がしたい人には、基本的な技術要素を知っておくと、IT業界のトレンドが良く分かるようになります。

DOMツリーとWindowオブジェクト

HTMLがブラウザに読み込まれると、HTMLの内容と同じツリー構造の「DOMツリー」が自動的に作られる。
JavaScriptでは、このDOMツリーを操作することで、HTMLを操作できる。
また、JavaScriptではあらかじめ用意されているWindowオブジェクトを使うことで、アラートボックスを出したり(window.alert関数)、HTMLの内容を取得・操作したり(window.documentプロパティ)、URL情報を取得したり(window.locationプロパティ)することができる。あらかじめ用意されている関数やオブジェクトはみんなWindowオブジェクトのプロパティである。このwindow.は省略することができる。

DOMの利用

DOMは、JavaScriptからHTMLの要素を操作するための仕組みのこと。ドキュメントをオブジェクトとして扱うモデル(Document Object Model)のこと。JavaScriptでHTMLの要素を操作する上で、知っておいた方が良い。
DOMではツリー構造でノード(HTMLの要素)へアクセスすることができる。JavaScriptからはID名でノードを取得し、操作することができる。
まず、HTMLの側に

<section id="section-1">
    <h2>セクション1</h2>
    <p>子ノード1</p>
    <p>子ノード2</p>
    <p>子ノード3</p>
</section>
<section id="section-2">
    <h2>セクション2</h2>
    <p>子ノード1</p>
    <p>子ノード2</p>
    <p>子ノード3</p>
</section>

などとし、JavaScriptの側に

document.getElementById('section-2').style.color = 'red';

とか、

var baseElement = document.getElementById('section-2');
var section2node2 = baseElement.childNodes[5];
section2node2.innerHTML = '子ノード2は変更されました';

とか、

var baseElement = document.getElementById('section-2');
var parentNode = baseElement.parentNode;
parentNode.removeChild(baseElement);

などとする。
DOMを使うことで、簡単にHTMLの要素をオブジェクトとして変えることができる。HTMLを用意してある特定の要素を変える、という点ではPHPに似ているが、フォーマットに

<div id="msg"></div>

などのID要素を指定した上で、JavaScriptから'msg'とか'#msg'などのIDで要素を特定しなければならない。(DOMを直接操作せずにフレームワークを用いることもできる。)

document.writeとinnerHTML

JavaScriptで文字列をページに出力するためには、document.write関数を使います。

document.write('<p>test</p>');

これで、現在の位置(スクリプトを実行した位置)にHTMLを出力できます。
指定の位置に出力したい場合は、まず、HTMLにidをつけてdivタグを表示しておきます。

<div id="header"></div>

そして、DOMで以下のように操作します。

var header = document.getElementById("header");
header.innerHTML = "<p>test</p>";

複数行にわたる文字列を入れたい場合は、行末に\をつけます。
応用として、

function OnButtonClick() {
    ...
}

のような関数の中でDOMを操作し、HTMLの側にリンクとして

<input type="button" value="Please Click." onclick="OnButtonClick();"/>

のようにすることが考えられます。

クロージャ

JavaScriptでは関数はすべてクロージャクロージャとは、「自分を囲むスコープにある変数を参照できる関数」である。

function func1() {
  var x = 1;

  function func2() {
    x = x + 1;
  }
  func2();
  console.log(x); // 2
}
func1();

JavaScriptは全ての関数がクロージャで、関数と同じブロックで宣言された変数を関数の中から参照することができる。この概念はプロトタイプチェインと似ていて、スコープチェインなどと呼ばれる。

プロトタイプベースのオブジェクト指向

JavaScriptはプロトタイプベースでオブジェクト指向を行う。
apllyメソッドやcallメソッドを使って「委譲」と呼ばれるオブジェクト指向を行うことが大きな特徴。
JavaScriptでは、クラスベースではなく、プロトタイプベースの「委譲」と呼ばれるオブジェクト指向を行う。上手く使うことで、あるメソッドを任意のオブジェクトに適用して実行したり、あるオブジェクトのメソッドを別のオブジェクトに関連づけさせて実行させることができる(委譲)。場合場合によってさまざまなメソッドをさまざまなオブジェクトに対して実行したり、あとでオブジェクトに対するメソッドを変更・追加したりすることもできる。

オブジェクト指向にクラスなんか必要ない!

JavaScriptの新しい点は、「オブジェクト指向にクラスなんか必要ない」ということ。
そもそも、C++Javaのようなクラスベースのオブジェクト指向は、オブジェクト指向であるとは言えるが、本当はクラスは必ずしも必要のないものである。
JavaScriptは、そこでもっと面白い道を選んだ。それが「プロトタイプチェーン」。オブジェクトは関数のプロトタイプを使って共通した関数を持つこと(つまり、同じプロトタイプを所有すること)で、オブジェクト指向を実現する。
関数はオブジェクトに束縛されない。いくらでもあとから関数を付け足せる。このような考え方を「委譲」と呼ぶ。
たぶん、クラスベースのオブジェクト指向が「机の上で設計図を書いている」感じに近いとすれば、プロトタイプベースのオブジェクト指向は「現場で部品を組み立てている」感じに近いと思う。

プロトタイプチェーンの基本

JavaScriptでは関数も第一級のオブジェクト。関数もオブジェクトとして扱われ、関数もオブジェクトのプロパティに格納することができる。JavaScriptではメソッドはただ参照されているだけに過ぎない。つまり、束縛されない。
プロトタイプチェーンは要するに、「同じ変数名で変数を探していって、p.sayがあればそれを、なければp.__proto__.sayを、それもなければp.__proto__.__proto__.sayを探す、といった感じ。
同じメソッドを持ったオブジェクトを量産するためには、「同じプロトタイプを所有する」ことで実現できる。たとえばobjB.__proto__とobjC.__proto__にどちらもobjAを代入して所有させれば、同じメソッドを別々のオブジェクトで共有できる。
ただし、通常は__proto__ではなくprototypeとnewを使う。newは、オブジェクトの生成、継承、初期化を行うコンストラクタ関数を呼び出して、prototypeの内容を自動的に__proto__に代入するかのように動作する。prototypeとnewを使うことで、クラスを使わなくてもオブジェクトの量産が可能になる。要するに、prototypeの内容を作った上でnewを使えば、自動的にprototypeの内容に基づいたオブジェクトを量産できる。まさに、これはこれでオブジェクト指向である。

thisを使った委譲

callは、あるオブジェクトにあるメソッドを関連づけて呼び出すことができる。
applyは、あるオブジェクトにあるメソッドを関連づけて呼び出すことができる。第二引数は配列で渡す。
bindは、あるメソッドに対してあるオブジェクトをbindで関連づける。

Ajax

WebでもGUIに負けないサービスを作れる

Ajaxを上手く使うことで、WebサービスでもGUIアプリケーションに負けない操作性を持ったアプリケーションを作ることができます。
きっかけは、Google Mapsのような、Webサービスなのにボタンやリンクが備わっていて、インタラクティブに操作・反応するWebアプリケーションの登場です。
そのごろは、XMLHttpRequestXMLを上手く使うことで、Google Mapsのような操作性を実現していました。今では、JSONを使ったり、時にはjQueryを使うこともあります。

参考文献

一部の内容で最強オブジェクト指向言語 JavaScript 再入門! - SlideShareを参考にしています。

簡単な説明

JavaScript

  • JavaScript
    • JavaScript
      • varとlet
      • 関数呼び出し
        • リンクやボタンからJavaScriptを実行するにはonclickに関数を指定する
      • windowオブジェクト
        • JavaScriptでは基本的にブラウザに用意されているwindowオブジェクトからブラウザやドキュメントを操作する
      • DOM
        • HTMLはDOMと呼ばれるツリーで操作する
      • プロトタイプチェーン
      • クロージャ
      • Ajax

JavaScript

JavaScriptはクライアントサイドのプログラミング言語
Perl/PHPのようにサーバーサイドでHTMLを吐くために使うのではなく、ブラウザ上でHTMLを操作するために使う
Perl/PHP掲示板やブログを作るためにあるとするなら、JavaScriptはブラウザ上でインタラクティブな操作や処理を行うためにある

DOM

DOMではHTMLを「ノード」の階層構造として表現する
ドキュメント要素を取得するには、たとえばgetElementByIdなどで行い、書き換えるにはinnerHTMLなどで行う
最近はdocument.writeよりもinnerHTMLやinsertAdjacentHTMLやappendChildを使うべきだとされている

プロトタイプチェーン

クラスとはまた違う、「プロトタイプを作ってオブジェクトを量産する」かのようなオブジェクト指向のスタイル
特に「委譲」と呼ばれる新しいオブジェクト指向の概念(あるオブジェクトの操作を別のオブジェクトにしてもらうようにお願いを立てる)がある

クロージャ

関数定義と同一スコープの変数に関数内部からアクセスできる

Ajax

Ajaxを使うことで、Google MapsのようにWebサービスでもGUI並みのインタラクティブな処理が可能となる