JavaScript

JavaScript

JavaScriptを
学ぶチュートリアル

第1章Hello, world!

Webブラウザ上で動作する唯一の言語であるJavaScriptは、あらゆるプログラマーにとって欠かすことのできないツールキットです。『JavaScript編』は、ソフトウェア開発者が日常的に使いこなしているツールを中心に、最新のテクノロジー(Node.jsES6など)を用いて、実用的でモダンなJavaScriptプログラムをできるだけ短期間で書き始められるよう構成されています。

本チュートリアル独自の特長は、JavaScriptをWebに限定せず、最初から汎用プログラミング言語として学ぶようにできている点です。実際、本チュートリアルのコード例はブラウザでの実行に縛られないようになっています。このようにして JavaScriptを「ストーリー仕立てで学べる」実用的な JavaScript入門書が完成しました。本チュートリアルは、Codeacademyのようなブラウザ上のオンラインチュートリアルや、MDN(Mozilla Developer Networkの公式JavaScriptチュートリアルと合わせて学ぶのにも最適です。

JavaScriptについて隅から隅までもれなく学ぶ必要はありません(そんなことをしたら数千ページを死ぬ気で学び倒さなければならなくなるでしょう)(図 1.11)。そうではなく、本チュートリアルではプロ開発者としての基礎を固めるのに必要な JavaScriptを学びます。

images/figures/flavian_amphitheater
図 1.1: ローマは一日にして成らず、JavaScriptも同じです

JavaScript編』はプログラミング経験が初めての方でも問題ありません(もちろんプログラミング経験があっても大丈夫です)。重要なのはプログラミング経験の有無ではなく、皆さんがこれまで以下の「開発基礎編」「Web基礎編」チュートリアルシリーズを貫くテーマである「技術の成熟精神( 1.1)」を身に付け始めているかどうかです。これらの「開発基礎編」「Web基礎編」を学び終えた方は、本チュートリアルを学ぶための準備ができています。

  1. コマンドライン編
  2. テキストエディタ編
  3. Git/GitHub編
  4. HTML編
  5. CSS & Design編
コラム 1.1. 技術の成熟

コンピュータを使いこなすうえで重要なのは、問題の原因を「自力で」見つけ出し、「自力で」解決できる能力です。本チュートリアルシリーズではこれを「技術の成熟精神」と呼んでおり、シリーズ全体を貫く重要なテーマに据えています。

技術の成熟精神」を身に付けるには、『コマンドライン編』『 Git/GitHub編』『HTML編』『CSS & Design編』で基礎をみっちり学ぶことはもちろんですが、何か問題や事例に遭遇したときに「基礎に立ち返って公式ドキュメントや教科書を読み返すべきか」それとも「ネットで解決方法をググるべきか」を見きわめられるようになることが肝心です。困ったときに何も考えずにググってしまううちは、技術の成熟精神を身に付けたとは言えません。

JavaScript編』では、こうしたスキルを身に付ける機会を豊富に用意しています。特に、既に述べたようにネット上にはJavaScriptの参考資料やブログ記事が溢れかえっていますが、基礎を固めると同時にこうした見きわめができていなければ、ネット上の資料やブログ記事を使いこなすのは難しいでしょう。ブログ記事は古いかもしれませんし、情報に誤りがあるかもしれません。公式ドキュメントでも情報の一部が更新されないままになっている可能性も考えられます。特に、日本語ドキュメントは英語版より古いことが多いので注意が必要です。

本チュートリアルの目標のひとつは、ネット上のおびたたしい情報の中から適切なものを見つけ出すスキルを身に付ける、つまり皆さんがドキュメントという宝箱を開けるための「鍵」となることです。著者はもっぱらMozilla Developer Network(MDN)のドキュメントを愛用していますが、これも含めて多くの有用な参考資料を本チュートリアルでその都度紹介いたします。

なお、Stackoverflow(英語版)というQAサイトもおすすめです(日本語版は情報が少なすぎるのでおすすめしません)。

特に、技術的に高度な内容に触れる際には、その情報を適切にググれるキーワードとURLも可能な限り添えるようにしています。たとえば JavaScriptで特定のCSSクラスにマッチする要素をページ上のすべての要素に返す方法を知りたい場合は、javascript css class return all elementsで探せます。

重要な情報は英語で書かれていることが多いので、英語力と、英語の技術ドキュメントやエラーメッセージを怖がらずに読むガッツも重要です。幸い、技術英語は比較的やさしい部類に入ります。著者が英語ネイティブでない場合は多少英文が怪しいこともありますが、むしろ英語ネイティブでない人の書くドキュメントは難しい言い回しが少ない分読みやすいでしょう。

本チュートリアルで、JavaScript開発のプロに欠かせないスキルを身に付けるまでの道のりを紹介します。

最初に、新しくプログラミング言語に初めて触るときの定番中の定番である「hello, world」プログラムを書いて、そこにさまざまなテクニックを盛り込んでいくことにします(1)。同時に「Node.js」と呼ばれる、広く使われている高速なJavaScriptプログラム実行環境も紹介します。本チュートリアルの理念「実際に手を動かす」に則って、早々に1でごくシンプルなJavaScriptアプリケーションを実際のWebにデプロイします。

「Hello, world」をマスターしたら、次はJavaScriptの「オブジェクト(object)」という概念についてある程度学びます。文字列オブジェクトについては2で、配列オブジェクトについては3で、その他のオブジェクトについては4で扱います。これらの章は、JavaScriptによる「オブジェクト指向プログラミング(object-oriented programming)」のやさしい入門書となっています。

5では「関数(function)」の基礎を学びます。関数は、プログラミング言語で必ずと言ってよいほど使われている概念です。さらに6では、「関数型プログラミング(functional programming)」と呼ばれるエレガントで強力なコーディングスタイルを学びます。

JavaScriptに組み込まれているオブジェクトの基本をひととおり学んだ後は、7で独自のオブジェクトを作る方法を学びます。具体的には、英語のフレーズ(phrase: 句、単語より大きく文より小さい単位)を定義するオブジェクトを定義して、そのフレーズが「回文(palindrome: 前から読んでも後ろから読んでも同じになる)」かどうかを調べるメソッドを作ります。

最初に実装する回文チェックメソッドはかなり初歩的なものですが、8では「TDD(test-driven development: テスト駆動開発)」と呼ばれる強力な手法を用いてメソッドを拡張します。同時に、ソフトウェア開発における一般的な「テスト」についてさらに詳しく学ぶと同時に、NPMモジュール(NPMはNode Package Managerの略)と呼ばれる完結したソフトウェアパッケージの作り方も学びます(このときに、JavaScriptのソフトウェアパッケージをNPMで管理する巨大なエコシステムに皆さんも参加することになります)。

9では、作成したNPMモジュールをJavaScriptWebアプリケーションに適用し、回文を検出するWebサイトを作り、この機会を利用してイベント(event)の概念とDOM操作(DOMはDocument Object Modelの略)についても学びます。最初はごくシンプルな実装からスタートし、アラート(alert)、プロンプト(prompt)、HTMLフォーム(form)などの洗練された拡張機能を徐々に追加していきます。

10では、ある程度大きなシェルスクリプトをJavaScriptで書く方法を学びます。JavaScriptは汎用プログラミング言語としての重要性を増しており、こうした用途も避けて通りにくくなっています。ファイルの読み込みやURLからの読み込みなどの例をこなし、最後に、ダウンロードしたファイルをHTML Webページのように操作する方法を紹介します。

11では、9や 10で学んだことを応用して、商用レベルのWebサイトを実際に構築します。特に、『CSS & Design編』で作ったサンプルアプリケーションを拡張することで、ユーザーのクリックに反応して画像やCSSクラスやページテキストをJavaScriptで動的に変化させる機能を追加します(Gitを使ってリポジトリを直接構築するので、『CSS & Design編』を終えていない方もイメージギャラリーのビルドやデプロイを行えるようになっています)。

本チュートリアルでは、動的レンダリングを行えるフロントエンドとデータベースのバックエンドを備えた本格的なウェブ開発までは扱いませんが、本チュートリアルを終える頃には、そのためのスキルを会得する基礎を十分身に付けられるでしょう。

本チュートリアルの最後に、JavaScriptの知識をさらに深められる参考資料のリンクや、フルスタックWeb開発を学べる「開発基礎編」「Web基礎編」チュートリアルを紹介します。本チュートリアルで学ぶJavaScriptの基礎知識は、SinatraRubyを学ぶときはもちろん、特にRuby on Railsでフルスタックウェブ開発を学ぶうえで非常に有用です。

1.1 JavaScriptについて

JavaScriptを最初に開発したのは、コンピュータ科学者Brendan Eichです(図 1.22。最初のJavaScriptが初期の商用WebブラウザであるNetscape Navigatorに搭載されましたが、このときは「LiveScript」という名前でした( 1.2)。この頃のJavaScriptの使いみちは、もっぱら『CSS & Design編』でも紹介したDOM(Document Object Model)操作が中心でした(その点は現在でも変わっていません)が、現在ではバックエンドでの利用や、汎用プログラミング言語としての利用も増えています。

brendan_eich
図 1.2: JavaScriptの生みの親Brendan Eich
コラム 1.2. 「名前が何だというのですか?」

名前が何だというのですか?バラをどんな名前で呼ぼうと、甘い香りを放つことに変わりはないではありませんか。

—ウィリアム・シェークスピア『ロミオとジュリエット』 (第二幕、場面二)より

現在私たちがJavaScriptと呼んでいる言語は、Netscape社では当初「LiveScript」と呼ばれていましたが、リリースが迫っていた当時は、今は無きサン・マイクロシステムズ社の開発したJava言語が大人気を博していました。Netscape社は、このJava人気にあやかろうとしてLiveScriptの名前を「JavaScript」に変更しました。そのため、当時の開発者たちは「JavaScriptとJavaは何か関係があるのか?」と果てしなく混乱したのです(答え: 両者は何ひとつ関係ありません)。

その後、ブラウザ間の互換性を高めるために、ECMAScript(「エクマスクリプト」と発音します)と呼ばれるJavaScriptの標準化版が誕生しました(当時、ブラウザごとにJavaScriptの挙動が細かく異なっていて深刻な問題になっていたのです)。

厳密なことを言えばですが、一般にJavaScriptと呼ばれている言語は本来ECMAScriptと呼ぶのが適切です。JavaScriptはあくまでECMAScriptの最も一般的な実装にすぎませんが、この言語が一般にJavaScriptと呼ばれているので、本チュートリアルでもこの慣習に従っています。

なお例外として、ECMAScriptのバージョン6を指すES6という短縮名を使うこともあります。なお、ES6では大規模な変更が行われてECMAScript JavaScript標準に便利な機能が多数追加されています。あまりにも便利になったので、「ES6はES5以前とは別の言語だ」と言う人もいるほどです。

なお、ES6の正式な仕様名は「ECMAScript 2015」です(ES5以前は仕様に年号を含んでいません)。バージョン番号と年号の微妙なずれがあまりにも紛らわしいので、ES6より新しい仕様を指すときは、もっぱらバージョン番号よりも年号を用いて「ECMAScript 2020」のように表記する方が一般的です。

最後に、JavaScriptのスペルのSをうっかり小文字にして「Javascript」としてしまうスペルミスが実に多いことは知っておいて損はないでしょう。公式に近いドキュメントでもそうしたミスがあるくらいなので、明らかなスペルミスというよりは事実上「やむを得ず黙認」されているのが現状です。個人的には、JavaScriptよりも「Javascript」の方が鼻につかなくて好ましいとこっそり思っていますが、スペルミスには違いないので、本チュートリアルでは技術的に正しい「JavaScript」で統一しています。

JavaScript編』では、JavaScriptのプログラミングを広く理解していただくために、主に以下の4つの方面からJavaScriptを攻略します。

  1. フロントエンド JavaScriptプログラム(ユーザーのブラウザ上で動作する)
  2. Node.jsのREPL(Read-Evaluate-Print Loop)によるコマンドプロンプトでの対話操作
  3. スタンドアロン3のJavaScriptファイル(NPMなど)
  4. シェルスクリプト(『テキストエディタ編』)

JavaScriptの最初の学習は、C言語誕生した頃からプログラミングの定番のお題となっている「Hello, world」を4種類作ることから始めることにします。hello, worldプログラムの作成作業には、システムが正しく設定されているかどうかの確認も含まれます。つまりhello, world!という文字列を画面に表示する簡単なプログラムを実行できれば、システムが正しく設定されているというわけです。hello, worldプログラムはごくシンプルに設計されていますが、プログラムを実行するという課題に集中できるようにするためでもあります。

JavaScriptの本来の用途は「Web上で実行されるプログラムを書くこと」であり、現在も最も一般的な用途でありつづけています。そこで、手始めにWebブラウザに挨拶文を表示するプログラムを書いてWebサイトにデプロイします。

続いて、Node.jsというJavaScript実行システムを用いて、同じJavaScriptプログラムを3とおりの方法で書きます。1つ目はNode.jsのREPL上で動かし、2つ目はhello.jsという名前のJavaScriptライブラリファイル内に書き、3つ目はhelloという名前の実行可能シェルスクリプトの中に書きます。

Node.jsについては後ほど詳しく説明しますが、これを使うとWebブラウザがなくてもJavaScriptをコマンドプロンプトで動かせるようになります。Node.jsの中には、Chromeブラウザで使われているV8と呼ばれる驚くほど高速で強力なJavaScriptエンジンが含まれています。

以降の説明は、皆さんが何らかのUnix互換システムを利用できる状態にあることを前提として進めます。ここで言うUnix互換システムとは、bashでコマンドプロンプトを動かせる「macOS」「Linux」「AWS Cloud9 IDE」などを指します(残念ながらWindowsはそのままではUnix互換システムにならないので、WSL 2をインストールするなど相当苦労して環境を構築する必要があります)。そうした環境がない場合は、Rails Girlsインストールレシピを参考に環境を構築することをおすすめします。Cloud9 IDEでJavaScript向けの開発環境を作成する場合は、javascript-tutorialという名前を開発環境に付けておくとよいでしょう(rails-tutorialと区別するため)。

Macユーザー向けのメモ: 可能でしたらシェル環境をmacOSのデフォルトであるzsh(z shell)からbash(Bourne-again shell)に切り替えておくことをおすすめします(本チュートリアルではどちらを使っても大丈夫なはずです)。切り替え方法は、コマンドプロンプトでchsh -s /bin/bashを実行してパスワードを入力し、ターミナルプログラムを再起動するだけで完了します。切り替え時にターミナルにいろいろ警告メッセージが表示されますが、すべて無視して構いません。

1.2 Webブラウザ内で動くJavaScript

JavaScriptは汎用のプログラミング言語として使われるようになってきていますが、もちろん本来のすみかであるWebブラウザでも活躍しています。そこで、最初の「hello, world」プログラムは、JavaScriptで作成した通知をWebページに表示することにしましょう。

まず、mkdir -pコマンドを実行してこのチュートリアル用のディレクトリを作成し4(必要に応じてこの中にもディレクトリを作成します)、touchコマンドでHTMLインデックスファイルを作成します5

$ mkdir -p ~/repos/js_tutorial
$ cd ~/repos/js_tutorial
$ touch index.html

次に、『Git/GitHub編』で学んだ方法を応用して、このプロジェクトをGitのバージョン管理下におきます。

$ git init
$ git add -A
$ git commit -m "Initialize repository"

この時点で、最初の編集を行う準備が整いました。まずはおなじみの、(JavaScriptを使わない)シンプルな HTML スケルトンをindexページに追加してみましょう(リスト 1.1)。これをWebブラウザで表示した結果を図 1.3に示します。

リスト 1.1: HTMLスケルトン index.html
<!DOCTYPE html>
<html>
  <head>
    <title>JavaScriptを学ぼう</title>
    <meta charset="utf-8">
  </head>
  <body>
    <h1>Hello, world!</h1>
    <p>このページにはJavaScriptで書かれたアラートがあります。</p>
  </body>
</html>
images/figures/html_skeleton
図 1.3: 最初の静的なindexページ

まだJavaScriptを足していないので、このままだとページの文面がうそになってしまいますね。そこで、コマンドを1つ含む以下のscriptタグをHTMLに追加することにします(どこに追加したらよいかはこの後説明します)。

<script>
  alert("hello, world!");
</script>

上のコードで使っているalert()は、JavaScriptの「関数(function)」を呼び出しています。JavaScript関数呼び出しの構文を図 1.4に示します。

関数呼び出しは「関数名」「かっこ()」を続けて書きます。

関数を関数名()のように書くとその関数が呼び出され、何らかの機能が実行されます。これを「関数呼び出し」といいます。関数を呼び出すには、関数名()のように丸かっこ()も付けなければなりません。

関数の種類によっては、関数呼び出しの()の中に「引数(ひきすう: argument)」を書けるものもあります。引数は0個(つまり()の中が空)のこともあれば、1個のこともありますし、2個以上書けることもあります。

関数にどんな引数をいくつ渡せるかは、関数ごとに決まっています。自分で関数を作るときは、どんな引数をいくつ渡せるかを自分で決めなければなりません。

図 1.4では関数呼び出しの末尾にセミコロン;が置かれていますが、これは「そのコード行がここで終わる」ことを表します。ご注意いただきたいのは、「関数呼び出しだからセミコロンを付ける」のではないということです(関数呼び出し以外の場合であってもコードの行末には原則としてセミコロンをおきます)。

関数を自分で定義する方法などについては5で詳しく説明します。

images/figures/function_anatomy
図 1.4: JavaScriptの関数呼び出しの構文

alert()関数の場合は、引数に「文字列(string)」を書けます(2)。ここに書いた文字列は、ブラウザ上のアラートボックスに表示されます。

それでは、いよいよindexページにalert()関数を追加して実際に動かしてみましょう(リスト 1.2)。

なお、このscriptタグはページのどこに置いても「一応」動きますが、HTMLのheadタグの中に置くのが普通です。特に、この後の 5.2のように外部のJavaScriptファイルをインクルードする場合はheadタグの中に置くのが定番です。

リスト 1.2: JavaScriptで「Hello, world!」する index.html
<!DOCTYPE html>
<html>
  <head>
    <title>JavaScriptを学ぼう</title>
    <meta charset="utf-8">
    <script>
      alert("hello, world!");
    </script>
  </head>
  <body>
    <h1>Hello, world!</h1>
    <p>このページにはJavaScriptで書かれたアラートがあります。</p>
  </body>
</html>

ブラウザ表示を更新すると、ブラウザ上部に「hello, world!」と書かれたアラートボックスが表示されます(図 1.5)。なお図はSafariブラウザの場合です(ChromeやFirefoxだとアラートボックスの細かなデザインや文言が少し異なる可能性があります)。

コラム 1.3. ブラウザごとにメッセージが異なる場合がある

残念ながら、ブラウザで表示されるさまざまなアラートボックスやバリデーションに表示されるブラウザ組み込みのデフォルトメッセージはブラウザごとに微妙に異なることがほとんどです(参考)。これは日本語でも英語でも発生します。ブラウザ組み込みのメッセージをどう書くかはブラウザの仕様に含まれていないので、ブラウザメーカーごとにまちまちなのが実情です。さらにブラウザの英語メッセージがブラウザメーカーによって日本語に翻訳されると、ばらつきがひどくなることもあります。今後ブラウザメーカーが手を組んでメッセージを統一しない限り、この問題は解決しないでしょう。

ブラウザごとのメッセージのばらつきは、通常はさほど問題にならないと思いますが、Webサイトのヘルプを書いたりスクリーンショットを撮影するときに対応が面倒になることがありますので、知っておいて損はないでしょう。

images/figures/js_hello_world
図 1.5: 「hello, world!」アラートボックスが表示された様子

1.2.1 作ったものをデプロイする

仕上げに、今作った素晴らしいJavaScriptアプリ(これでもJavaScriptアプリですよ)をWebサイトにデプロイしましょう。これまで『Git/GitHub編』『HTML編』『CSS & Design編』で行ったのと同じ要領で、GitHub Pagesに無料のWebサイトをホスティングすることにします。

このようにチュートリアルの早い段階でWebサイトへのデプロイを行うことで、ここで学んだ概念が実際に動くことを強力に実証できます。このJavaScriptアプリが素晴らしいというのは単なる冗談ですが、それはさておき、本チュートリアルでもこのように実際に動くWebサイトをデプロイします。今では数秒でデプロイを完了できますが、ほんの数年前まではそれはそれは面倒な作業でした。

まず、以下を実行してリスト 1.2の変更結果をGitにコミットしましょう。

$ git commit -am "Add a JavaScript 'hello, world'"

次に、GitHub上にjstutorialという名前で新しいリモートリポジトリを作成します(図 1.6)。ここでは詳しく説明しませんので、手順がわからない場合は『Git/GitHub編』をご覧ください。

images/figures/new_repository
図 1.6: GitHub上に新しいリポジトリを作成する
コラム 1.4. デフォルトのGitHubブランチ名

2020年10月、GitHubから次のアナウンスがありました。新規作成されるリポジトリのデフォルトのブランチ名が、従来のmasterからmainに変更されたというものです。デフォルトブランチ名が変更された理由についてはWikipediaに譲りますが、masterもまだ広く使われているため、皆さんが今後ドキュメントや書籍などでmasterというブランチ名を見かけることもあるかもしれません。その場合は適宜mainに読み替えて理解すると良いでしょう。詳しくはブログ記事「Default Git Branch Name with Learn Enough and the Rails Tutorial(英語)」をご参照ください。

次に、以下のコマンドを実行してリモートリポジトリを設定し、ブランチをプッシュします(<ユーザー名>にはGitHubのユーザー名を記入します)。上述したように、本チュートリアルではデフォルトブランチをmasterにする前提で進めますが、 1.4で説明したmainブランチに変えた方は、以後のコマンドでもmainブランチに読み替えて作業してください。

$ git remote add origin https://github.com/<ユーザー名>/js_tutorial.git
$ git push -u origin master

あとはGitHubリポジトリの「Settings」タブの左サイドバーにある「Pages」をクリックして(図 1.7)を編集し、GitHub Pagesでmasterブランチをするよう設定します(図 1.8)。このとき、リポジトリが「public」であることを確認しておいてください(privateだとGitHub Pagesを利用できません)。

これでデプロイは完了です。

images/figures/github_settings
図 1.7: GitHubリポジトリの設定を編集する
images/figures/github_pages_master_branch
図 1.8: masterブランチをGitHub Pagesで公開する設定

これで、以下のURLをブラウザで開くと今作ったindexページのJavaScriptコードが動き、アラートボックスが表示されます6

https://<ユーザー名>.github.io/js_tutorial

図 1.5のときとまったく同じ「hello, world」が表示されていますが、今度はインターネット上でちゃんと「実際に動いている」(図 1.9)点が大きな違いです。たった1行とはいえ、あなたが書いたJavaScriptコードが誰からでも見える場所で実際に動いているのです!

images/figures/js_hello_world_live
図 1.9: インターネット上で JavaScriptのhello, world!ページが実際に動いている様子

1.2.2 演習問題

  1. 先ほどのアラートボックスに続けて、もうひとつアラートボックスを表示するとどうなるでしょうか?実際に試してみてください。終わったら元に戻しましょう。

1.3 JavaScriptを「REPL」で動かす

お次は、今のhello worldプログラムをREPL(「レプル」と発音します)で動かしてみましょう。REPLは「対話機能」とも呼ばれ、コマンドプロンプト上で「Read(読み取り)」「Eval(評価)」「出力(Print)」を繰り返す(Loop)という意味です。RubyにもirbというREPL機能があるように、今どきのプログラミング言語にはREPL機能があるのが当たり前になっています。もちろんJavaScriptも例外ではありません。お気づきかと思いますが、JavaScriptには2種類のREPLがあります。

1.3.1 ブラウザコンソール

1つ目のREPLは、ブラウザの「コンソール(console)」で行えます。今どきのブラウザは標準でコンソールなどの開発ツール(devtools)が利用可能になっているのが普通です。Google Chromeブラウザでは最初からdevtoolsが含まれていますが、Safariブラウザの場合は 開発メニューを有効にする必要があります。

本チュートリアルではdevtoolsについて詳しく説明しませんので、自分が使うブラウザでdevtoolsをセットアップする方法については例の「技術の成熟」精神( 1.1)を発揮して自力でやってみてください。

たいていのdevtoolsは、ブラウザ画面を右クリック(またはCtrlキーを押しながらクリック)して、「検証」(Chrome)や「要素を調査」(Firefox)や「要素の詳細を表示」(Safari)あたりをクリックすればWebインスペクタが表示されます(図 1.10)。SafariでWebインスペクタを表示したときの様子を図 1.11に示します。

images/figures/inspect_element
図 1.10: Safariの「要素の詳細を表示(Inspect Element)」メニュー
images/figures/developer_tools
図 1.11: SafariでdevtoolsのWebインスペクタを表示した様子

あとはページの下に表示されたWebインスペクタで「Console」タブ(または同等のタブ)をクリックすれば、コンソールにアクセスできるようになります(図 1.12)。

後ほど 5.2で説明するように、コンソールは実に有用なデバッグツールでもあります。コンソールは、DOM(Document Object Model)やアプリケーション環境を裏舞台から調査して、アプリケーションに影響を与える可能性のある警告やエラーを確認できます。

コンソールにはさまざまな警告やエラーが赤い文字で大量に表示されることもあります。エラーのほとんどは「無視してよい」ものですが、中には「無視してはいけない重要な警告やエラー」もたまにあります。この見分けがつくようになれば、皆さんに「技術の成熟」精神が身についた証拠です。

今の段階ではおそらくコンソールにエラーは表示されないはずですが、皆さんのブラウザ設定によっては何かエラーが表示される可能性もあります。でも今の段階で表示されるエラーは「すべて無視しても大丈夫」なのでご安心ください!どうか怖がらないでいただきたいと思います(今は、たとえエラーが出ても目をそむけない度胸を養うことが重要です)。

images/figures/console
図 1.12: JavaScriptを対話的に実行できるコンソール

さて、コンソールのREPLでhello worldプログラムを書く準備がこれで整いました。

コンソールのREPLでメッセージを表示するには、先ほどのalert()関数ではなく、consoleというJavaScriptの「オブジェクト(object)」を使います。

JavaScriptのconsoleオブジェクトは、「コンソールそのもの」と、コンソールに関連する「データ」やさまざまな「関数」などを表現します。consoleオブジェクトにはlog()という関数が備え付けられていて、この関数の引数に何か文字列を渡すと、その文字列を(ブラウザそのものではなく)コンソール上に表示できます。

consoleオブジェクトのlog()関数を呼び出すときは、以下のようにオブジェクト指向言語で広く用いられている「ドット(.)記法」を用います(リスト 1.3)。

リスト 1.3: コンソールでhello, worldを出力する
> console.log("hello, world!");

log()は関数の一種ですが、特に上のように特定のオブジェクトに続けてドット.記法で書いて呼び出す関数は「メソッド(method)」といいます。メソッドは関数の一種であり、呼び出し方に特徴があります。

なお、リスト 1.3console.log("hello, world!");をコンソールに入力するときは、冒頭にあるコマンドプロンプト(>)を含めないでください。

正しくコンソールに入力してReturnキーを押すと、図 1.13のような結果になるはずです(その下に表示されている「undefined」については、 2.3で後述しますので今は気にしないでください)。

images/figures/console_hello_world
図 1.13: ブラウザコンソールにhello, worldが出力された様子

ところで勘の鋭い方は、リスト 1.3の末尾には図 1.4のとおりにセミコロン;が置かれているのに、図 1.13の末尾にはセミコロンがないことにお気づきかもしれません。いい点を衝いていますね!

実を言うと、対話型コンソールの場合は末尾のセミコロンはあってもなくても動作は変わりません。それを示すために図 1.13ではわざとセミコロンを入力しなかったのです。実際、ベテランがREPLで何かするときは、いちいち末尾にセミコロンを入力しないのが普通です。「セミコロンを付ける派」と「付けない派」がいることを知っておくと、他の人が書いたJavaScriptコードを読んで戸惑わずに済むでしょう。

本チュートリアルでは、コンソール入力についても「セミコロンあり」の書式で統一しています。

1.3.2 Nodeのプロンプト

どんなブラウザでも必ずJavaScriptプログラムを実行できるようになっています。しかし、ブラウザとは無関係に、コマンドライン上で実行する汎用プログラミング言語としてJavaScriptを扱うこともあります。そのためには、JavaScriptプログラムを評価して実行する何らかのコマンドライン用プログラムを別途インストールして使うことになります。現代では、コマンドラインでJavaScriptを動かすのに使うプログラムといえば、ほぼNode.js一択です(「ノードジェーエス」と発音しますが、しばしば単に「Node」と略記されます)。

コラム 1.5. 参考: Denoについて

2020年頃から、Node.jsの後継としてDenoが急速にクローズアップされつつあります。Denoの作者はNode.jsの作者でもあるRyan Dahlで、Node.jsのさまざまな問題点(npmパッケージの煩雑な管理やセキュリティなど)を抜本的に改善するためにDenoをリリースしました(参考)。Denoは「Node」のスペルを並べ替えた名前になっていて、アイコンが恐竜(Dinosaur)なのもDenoのもじりなのが面白い点です。

Denoは2021年7月の時点ではまだ発展途上の段階にあり、Node.jsは長く使われていて情報も多いので、Node.jsからDenoに急いで乗り換える必要はまだないと思われますが、今後DenoがNode.jsに取って代わる可能性も考えられるので、ときどき動向をチェックしておくとよいでしょう。

Node.jsは皆さんの使っているコンピュータに既にインストールされている可能性もあります。以下のようにwhichコマンド(『コマンドライン編』を参照)を使えばさくっとチェックできます。

$ which node
/usr/local/bin/node

nodeという実行ファイルへのパスが表示されれば、Node.jsを使える状態になっています。macOSにNode.jsがインストールされていない場合は、 Homebrewがインストール済みであれば、以下のコマンドを実行するだけで最新のNode.jsをインストールできます。

$ brew install node

Node.jsがインストール済みの場合は、念のために以下を実行してNode.jsを最新バージョンに更新してください。

$ brew upgrade node

Homebrewを使わずにインストールする場合は、Node.jsサイトに記載されている指示に沿ってインストールします。

インストールが終わっていれば、Node.jsの実行は簡単です。コマンドラインで以下のようにnodeというコマンドを実行するだけです(リスト 1.4)。

リスト 1.4: コマンドラインでNodeプロンプトを起動する
$ node
>

Node.jsを起動すると表示される>は、ブラウザコンソールのときと同様、Nodeのプロンプトを表します。>が表示されているときはNodeのコードを入力可能であることを示します。間違えて>を入力しないようにしましょう。

なお本チュートリアルでは、特記しない限り「コンソール」はブラウザコンソールとNodeコンソールの両方を指すことにします。

さて、Nodeプロンプトでhello worldプログラムを動かすには、Nodeプロンプトに以下を入力します(リスト 1.3)。

> console.log("hello, world!");
hello, world!

なお、Nodeコンソールでもundefinedが表示される可能性がありますが、無視して構いません(詳しくは 2.3で説明します)。

ご覧いただいたように、hello worldを表示するプログラムは、ブラウザコンソールでもNodeプロンプトでも同じなのです。

> console.log("hello, world!");

1.3.3 演習問題

  1. ブラウザコンソールでわざとalert()を実行したらどうなるでしょうか?同じことをNodeコンソールでやった場合はどうなるでしょうか?

1.4 JavaScriptコードをファイルに書く

ブラウザコンソールやNodeコンソールのようなREPL環境でJavaScriptを実行できるのはとても便利です。しかし「本物のプログラミング™」はテキストエディタで開いたファイルの中で行うものです。そこで今度は、これまで2種類のREPL環境で実行したhello worldプログラムをファイルに保存して実行してみましょう。ファイルに保存したJavaScriptプログラムは、この後の 5.2からテンプレートとしても使い回す予定です。

helloプログラムを保存するJavaScriptファイルを、以下のコマンドで作成します(拡張子.jsは、JavaScriptファイルを表します)。

$ touch hello.js

続いて、このファイルをお使いのテキストエディタで開き、リスト 1.5のコードを入力します。このコードは、コマンドプロンプト >がない点を除けばリスト 1.3のコードとまったく同じであることにご注目ください。

リスト 1.5: hello, worldプログラムをJavaScriptファイルに書く hello.js
console.log("hello, world!");

変更を保存すれば、先ほどNodeプロンプトを起動するのに使ったのと同じnodeコマンドを以下のように実行することで即座にhello worldが表示されます(リスト 1.4)。違いは、nodeコマンドの後ろにファイル名を引数として追加した点だけです。

$ node hello.js
hello, world!

今度も「hello world!」が表示されましたが、ターミナル画面にはNodeプロンプト >抜きで表示されています。なお、内部では先ほどのundefinedが戻り値として返されていますが、対話的な実行ではないのでターミナルには表示されません。

たった1行のシンプルなコード例ですが、これは大きな進歩です。ブラウザコンソールやNodeコンソールは長いJavaScriptプログラムを実行するには不向きですが、ファイルに保存すればいくらでも長いプログラムを書けるからです。

1.4.1 演習問題

  1. console.logに渡す引数をリスト1.6のように2つにするとどうなるでしょうか?ブラウザコンソール、Nodeコンソール、JavaScriptファイルでそれぞれ試してみてください。
リスト 1.6: 引数を2つに増やす hello.js
console.log("hello, world!", "how's it going?");

1.5 JavaScriptをシェルスクリプト内で実行する

 1.4で動かしたコードはまったく問題なく動きます。しかし実用を考えると、JavaScriptプログラムをコマンドラインのシェルで動かす場合は、『テキストエディタ編』で学んだ「実行可能スクリプト(executable script)」の形にしておく方が有用なことがよくあります。

JavaScriptがブラウザなしでもコマンドラインで動くようになったおかげで、今やJavaScriptは従来の「Ruby」「Python」「Perl」と並ぶシェルスクリプト記述言語としても十分使えるようになってきました。つまり、拡張子.jsを付けていちいちnodeコマンドで実行しなくても、普通のシェルスクリプトと同じようにいきなりコマンドプロンプトで実行できるということです。

Node.jsを用いて実行可能スクリプトを作成する方法を見てみましょう。手始めに以下を実行して、helloというファイルを作成します7

$ touch hello

今作ったファイルに.jsという拡張子がない点にご注意ください。拡張子を付けなかった理由は「ファイル名だけで使い方がわかる」「どの言語で書かれたのかをユーザーに見せる必要はない」からです。

もうひとつの理由は、使った言語を隠しておけば、今後言語を他のものに変えても使い方が変わらずに済むためです。hello.jsという名前のままだと、今後これをRubyで書き直したらhello.rbという名前にしなければならなくなり、コマンドプロンプトでの使い方も変わってしまって不便です。helloのような単純なプログラムではそこまで気にする必要もありませんが、今後ある程度大きなシェルスクリプトを書くようになってくればありがたみがわかってくると思います。詳しくは 10.3で解説します。

さて、実行可能スクリプトに変えるには少々工夫が必要です。具体的には2つのステップがあります。

1つ目は、『テキストエディタ編』で学んだ「shebang」をリスト 1.5のコードの冒頭に追加して、「このスクリプトはnodeで実行しなければならない」という情報をシステムに伝えられるようにします。

shebang行の記述方法はシステムによって変わることがある点に注意が必要です(つまり環境が変わると動かなくなる可能性があるのです)。以下のようにwhichコマンドを使えば正しいパスを確認できます。

$ which node
/usr/local/bin/node

上で確認したパスをhelloファイルのshebang行に反映した結果をリスト 1.7に示します。

リスト 1.7: hello, worldのシェルスクリプト版 hello
#!/usr/local/bin/node

console.log("hello, world!");

このファイルを 1.4のときと同様にnode helloコマンドで実行することも可能ですが、本物のシェルスクリプトならnodeを書かなくても実行できるべきです(そのためにshebangを書いたのですから)。

このファイルはそのままでは実行できません。そこで、2つ目の手順として以下のようにchmodコマンドで+x(実行権限を追加)オプションを指定します(chmodは「change modeの略」とおぼえましょう)。

$ chmod +x hello

これでhelloファイルが実行可能になったはずです。

作ったスクリプトは、まだPATH環境変数(『テキストエディタ編』)のパスが通っていないので、helloだけでは実行できません。以下のように冒頭に./を追加して./helloと入力することで実行できます。なお、このドット.は「カレントディレクトリ」(現在のディレクトリ)を意味します。PATH環境変数(『テキストエディタ編』)のパスが通っているディレクトリにhelloファイルを移動すれば、helloと入力するだけで任意のディレクトリから実行できるようになります。

$ ./hello
hello, world!

これで、いつでも手を加えて改良できるJavaScriptシェルスクリプトが動くようになりました!先ほど述べたように、実際に役に立つユーティリティスクリプトの例を 10.3で紹介します。

本チュートリアルでは以後、主にREPLを用いて初期調査を行い、最終的にはJavaScriptを含んだファイルの形に落とし込みます(JavaScriptのみの場合もHTMLの場合もあります)。

1.5.1 演習問題

  1. 今作ったhelloスクリプトを、自分の環境のPATH環境変数が通っているディレクトリに追加して、./を冒頭に追加しなくてもhello入力するだけでいつでも実行できるようにしてみてください(『テキストエディタ編』によいヒントがあります)。
1. 本画像はパブリックドメインです。
2. 画像引用元: Wikimedia(2018-02-17)、Copyright © 2012 Darcy Padilla、クリエイティブ・コモンズ「表示 - 継承 3.0 非移植 (CC BY-SA 3.0)」 ライセンス条項に基づき無改変にて利用。
3. standalone: 単独で利用できる。
4. Cloud9などのクラウドIDEを使う場合は、本チュートリアルのコマンドでホームディレクトリを表す「~」の部分を常に「~/environment」に置き換えることをおすすめします。こうすることで普通のコマンドプロンプトと挙動が同じになります。
5. こうしたコマンドについては『コマンドライン編』でおさらいできます
6. URLのドメイン名をカスタムドメインに変えることもできます。詳しくはGitHubのドキュメントや『Learn Enough Custom Domains to Be Dangerous』をご覧ください。
7. 作成したファイルの改行コードが「CRLF」になっていると、シェルスクリプト実行時に「bad interpreter」エラーが発生する可能性があります。WindowsではデフォルトでCRLFが使われ、macOSやLinuxではデフォルトでLFが使われます。エラーが発生した場合は、エディタで改行コードをCRLFからLFに変更することで修正できます。
第1章 Hello, world! JavaScript編