JavaScript入門
ここではまずTypeScript(TS)の元になっている言語であるJavaScript(JS)について学んでいきましょう。
実行環境について
ブラウザ上で動かす場合
このテキストブックでは「実行」ボタンを押すと実行できるような機能があります。 ソースコードをクリックすると中身の編集も出来るので、ちょっとした動作を試すには便利です。
console.log("こんにちは!");
テキストブック以外でブラウザ上でJavaScriptを実行したい場合はいくつかのサービスやブラウザの機能を使えます。
ブラウザの機能を使う場合は右クリックで「検証」を押したあとに出てくる開発者ツールの中から「コンソール」を選択してみましょう。 コンソールタブからはJavaScriptのREPL(Read-Eval-Print Loop)と呼ばれる、ユーザーが入力したソースコードを即時に評価するプログラムを使うことができます。
例えば次のソースコードをブラウザのREPLに貼り付けてみましょう。
1;
1
と表示されたと思います。
これはJavaScriptで1を評価すると数値そのものが帰ってくるためです。
1 + 1;
2
と表示されたと思います。
これはブラウザが1 + 1
を評価(実行)して、その結果が表示されています。
このようにブラウザのコンソールを使うとJavaScriptを一行一行実行していくことができます。
その他にはWebサービスとしてJavaScriptを実行できる環境が有ります。
- TypeScriptプレイグラウンド
- メインはTypeScriptの実行環境
- エラーや補完が極めてわかりやすいので初学者から幅広く使える
- Wandbox
- JS/TS以外のも様々な言語が使える
- JSFiddle
- 海外製。HTMLなども含めて検証できる
Node.jsで動かす場合
console.log
JavaScriptではconsole.log
を使うとコンソールに値が表示されます。
コンソールとはブラウザでは管理者ツールのconsoleタブ、Node.jsでは標準出力(ターミナルの画面)を指します。
JavaScriptに限らずプログラミングでは一般的にabcdefg
やあいうえお
, グランパーク東宝8
などの文字の並びのことを「文字列」と言います。
JavaScriptでは文字列を表現するときは'
(シングルクォート)、または"
(ダブルクォート)で文字列を囲みます。
他の言語ではシングルクォートとダブルクォートで文字列の中の挙動が異なる、などがありますが、JavaScriptにおいては両者にはほぼ違いがありません。 実際の開発現場では機械的にどちらかに揃えるツールを導入したり、あるいはルールでどちらかを使うとエラーにする、などのルールが設定されていることがあります。
'abcdefg';
"あいうえお";
"グランパーク東宝8";
"12345"; // これは12345を数値としてではなく文字列として宣言している
また多くのプログラミング言語にはコメント機能があります。 コメントはプログラムの実行時は無視されるもので、 ソースコードの説明などを人間や他のツールにわかりやすく書いておくことなどのドキュメントに使われます。
JavaScriptでは//
を使うと以降行末までがコメントとして扱われます。
// 一行コメント
// console.log("ここはコメントの中なので実行されない");
console.log("ここはコメントの前"); // console.log("ここはコメントの中");
/*
を使うと次に*/
が出てくるまでの間を複数行のコメントとして扱います。
/*
この中はコメントなので
console.log("とかかいても実行されない");
*/
console.log("ここはコメントの外");
実際は複数行コメントは、ルール上でこのレイアウトで書くことを要求している特殊なドキュメントを書くときくらいにしか使われません。
console.log
を使うとプログラムの最中に様々な情報を表示することができます。
一般的にconsole.log
に該当する処理は、他の言語ではprint
と呼ぶことが多いため、console.log
を多用して情報を表示し、デバッグ(プログラムのバグを見つけること)をprintデバッグなどと読んだりします。
練習問題
ブラウザ上でconsole.logの中身を今日の日付に変えてみましょう。
console.log("ここの中身を変えてみてください");
文と式
JavaScript/TypeScriptに限らず、大半のプログラミング言語は文(statement)と式(expression)という構成要素で成り立っています。
式 (expression)
式とは評価するとなんらかの値になり、変数に代入することができるもののことを言います。
例えば 1 + 1
は、評価(実行)すると2
という値になります。
この1 + 1
という計算や結果の2
という数値そのものも式となります。
// 1という式の評価値を表示
console.log(1 + 1);
// 2という式の評価値を表示
console.log(2);
// 1 + 1 という式の評価値をsumに代入
const sum = 1 + 1;
文(statement)
対して文は、処理する1ステップ、あるプログラムの流れのことを言います。
文を上から下に処理することでプログラムが実行されます。
処理する文1;
処理する文2;
処理する文3;
文としては代入文や、if
文などが存在します。
const hoge = 1 + 1;
const isTrue = true;
if (isTrue) {
console.log("True!!");
}
JavaScript/TypeScriptにおける文は末尾に;
をいれる必要があります。文章の区切りですね。
数値計算
JavaScript/TypeScriptでは様々な計算をすることができます。
四則演算
まずは四則演算を見てみます
console.log(1 + 1); // 足し算
console.log(1 - 10); // 引き算
console.log(1 * 10); // かけ算
console.log(500 / 5); // 割り算
JavaScriptに限らずプログラミングの世界ではかけ算を*
,割り算を/
で表現することが一般的です。
また、算数の授業で出たように足し算引き算よりもかけ算の優先度が高いです。
console.log(2 + 3 * 5); // 3 * 5 が先に計算される
これを制御するには()
で優先したいグループを囲いましょう。
console.log((2 + 3) * 5); // 2 + 3 が先に計算される
べき乗・剰余
console.log(4 ** 2); // 4の2乗
console.log(10 % 5); // 10を5で割ったあまり(0)
console.log(10 % 4); // 10を4で割ったあまり(2)
剰余の使いどころ
剰余は、初めて聞く言葉かもしれません。利用例を解説します。 まず、剰余が0であれば、「割られる数」は「割る数」の倍数であることが確認できます。
console.log(14 % 7); // 14 は 7の倍数
さらに、剰余はグルーピングに利用できます。 例えば「今日の100日後の曜日」を求めるとき、100 日分カレンダーを辿るのは大変です。 1週間は7 日なので、7 日後は同じ曜日となります。 14 日後も同じ曜日となります。21 日、28 日、35 日... 7 の倍数日後は同じ曜日になります。
console.log(100 % 7); // 100 / 7 のあまりの2
これを利用し、100 日 を 7 日 で割ってみます。剰余は 2 となります。 今日の曜日と同じであれば剰余は 0、明日の曜日と同じであれば剰余は 1、明後日と同じ曜日であれば 2、と簡単に計算が可能です。 これは、曜日が 7 種類あることを利用したグルーピングです。
文字列
複数の文字列をまとめて1つの文字列に結合することができます。
JavaScriptでは文字列の結合には+
演算子を使います。
console.log("mo" + "no");
console.log("あいう" + "えお");
JavaScriptでは数値と文字列は区別されています。
そのため+
を使う際の両辺の値によっては意図しない結果になることもあります。
console.log("4" + "2");
console.log(4 + 2);
変数
計算結果を一度しか使わないのであれば、電卓のように変数は使用する必要が有りません。
500 / 10 ; ==> 50
そうでない場合、例えば「あるゲームの上位100人対してプレゼントを配布する」という処理を考えます。
このような場合にはまず上位100人をメモしておき、一人ずつ処理する流れをとる、、、というように、上位100人の一覧を参照しやすいようにメモとして残しておいたほうが便利でしょう。
このメモのことをプログラムでは 変数(variable
) と呼び、何かしらの名前をつけて計算結果を保存しておくことができます。
変数宣言
JavaScriptで変数を使う前には「こういった変数を使います」というのをプログラム上に示す必要があります。 これを変数宣言と言います。
JavaScriptでは変数の宣言にconst
またはlet
というキーワードをを使います。
(実はもう1つvar
での宣言も可能なのですが、var
は意図しない挙動を招きがちであるので現代では使用が非推奨となっています)
let
JavaScriptではlet
を使うと再代入可能な変数を宣言できます。
let 変数名 = 初期値;
例えば変数名language
で初期値が'Perl'
の変数を宣言するには次のように書きます。
let language = "Perl";
また、一度宣言した変数をconsole.log
するとその中身が表示されます。
let language = "Perl";
console.log(language);
ただしまだ宣言していない変数を表示しょうとするとエラーになります。
console.log(bar);
=
は数学的な「右辺と左辺が等しい」ではなく「値の代入(割当、紐づけ)」を意味します。
次のフローで動作します
- 右辺を評価(実行,
evaluate
) - その結果を左辺の変数に保存する
次のようなプログラムがあった場合は最終的にhitpoint
は10になります。
// 最初に hitpoint に 100を代入
let hitpoint = 100;
// hitpoint に (100 - 90)の結果を再代入
hitpoint = hitpoint - 90;
console.log(hitpoint);
またlet
は宣言する際に初期値を設定しないことも可能です。
let title;
console.log(title);
この場合はundefined
という未定義を意味する値で初期化されます。
練習問題
以下のコードの続きを書いてみましょう
let
で変数名app
, 値がDify
の変数を宣言- 変数
app
の中身をconsole.log
で表示
let ...
let独自の演算子
ところで数値を1ずつ上下することをインクリメント/デクリメントと呼びます。
let
で定義した変数は1ずつ数を上下するインクリメント/デクリメント演算子があります。
let number = 0;
number++; // インクリメント演算子
console.log(number);
++number; // ++ は前に書いてもよい
console.log(number);
--number; // デクリメント演算子
console.log(number);
number--; //同じように前後ろどちらでもよい
console.log(number);
厳密に言うと++
, --
を変数の前か後ろに書くかで微妙な差が存在します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Increment
テンプレートリテラル
さて変数の中身の表示はできましたが、ここで先程やった文字列と変数を組み合わせることを考えてみましょう。
例えば「今日は<変数>月です」のような表示をconsole.log
を使って考えてみます。
今までの知識を使うと文字列結合を使って表せそうです。
let month = 7;
console.log("今日は" + month + "月です");
この程度なら良いのですが、表示したい変数が増えていくとどんな文字列になるのかパット見でわかりづいらいです。
let month = 6;
let title = 'mono';
let author = 'あfろ';
console.log( month + "月までやっていたアニメは" + title + "で作者は" + author + '先生です');
JavaScriptではテンプレートリテラル機能があり、これを使うともう少し実態と同じように書けます。
テンプレートリテラルは\``(バッククォート、バックチック)で囲います。
テンプレートリテラル中に変数の中身を表示したい場合は
${変数名}`のようにします。
let month = 6;
let title = 'mono';
let author = 'あfろ';
console.log(`${month}月までやっていたアニメは${title}で作者は${author}先生です`);
${}
の中は実際は式が書けるので、このように計算結果もいれられます。
console.log(`10 * 100 = ${10 * 100}`);
また、テンプレートリテラルは改行もみたままにすることができます。
let msg = `こうして
改行すると
反映される`;
console.log(msg);
同じことをテンプレートリテラルを使わずにする場合、改行を表す特殊な文字\n
を使う必要があります。
let msg = "こうして\n改行すると\n反映される";
console.log(msg);
練習問題
以下プログラムをテンプレートリテラルでの文字列に直してみよう。 また、テンプレートリテラルの中で計算をして「今日は7月です。来月は8月です」のような文章を表示するようにしてみよう。
let month = 7;
console.log("今日は" + month + "月です");
const
const
を使用すると再代入不可な変数とその初期値を宣言できます。
const 変数名 = 初期値;
次のように再代入をしようとするとエラーが発生します。
const airline = 'jal'
airline = 'ana';
他の言語をやったことがある方なら「constは定数か」となるかもしれません。
JavaScriptのconstはプリミティブ値ならほぼ定数のような挙動をしますが、厳密には定数ではないため、オブジェクトなどの場合は定数として考えるとびっくりする挙動をします。 あくまでconstは変数の再代入を禁止する構文、として理解しましょう。
練習問題
- 次のコードをconstで書き直してみよう
- ヒント:
hitpoint
を再代入することはできないので、result
などの新しい変数を導入しよう
- ヒント:
// 最初に hitpoint に 100を代入
let hitpoint = 100;
// hitpoint に (100 - 90)の結果を再代入
hitpoint = hitpoint - 90;
console.log(hitpoint);
変数名のルール
変数名にはいくつかの特徴があります
1 大文字小文字の区別がある
const BAR = '123';
const bar = 456;
console.log(`BAR is ${BAR}`);
console.log(`bar is ${bar}`);
2 Unicodeの文字と$
, _
, 数字を使える。ただし数字では始められない
const ねこ = 'cat';
console.log(`ねこ is ${ねこ}`);
const 山梨の熊 = 'ツキノワグマ';
console.log(`山梨の熊 is ${山梨の熊}`);
const _bar = 'foo';
console.log(`_bar is ${_bar}`);
const Cicada_3301 = 'puzzle';
console.log(`Cicada_3301 is ${Cicada_3301}`);
const $ = 'ドル';
console.log(`$ is ${$}`);
ということで日本語を変数名にすることも可能です。 また変数名の大文字小文字の制限も特にありません。大文字で変数にすることも可能です。
とはいえ実際は慣例的に次のようなことが多いです。
- 定数はすべて大文字
- 型名は大文字から始める
- 変数は小文字で始める
$
はjQueryなどのDOMを操作する際のオブジェクトにつける- 日本語の変数としては極力使わない
- ただしテストコードなどで関数名として使うケースもあるにはある
- 2単語以上の組み合わせは各単語の先頭の文字を大文字にする
- camelCase(キャメルケース)と言います
- 特に先頭が大文字から始まるのをUpperCamelCase, PascalCase
- 先頭が小文字から始まるものをLowerCamelCase, camelCaseなどと言います
- camelCase(キャメルケース)と言います
(言語によってはsnake_case
と言ってアンダースコア(_
)を区切りに使うものもありますが、JavaScriptはcamelCaseが主流です)
メタ構文変数
また、すでにいくつか出てきていますが、プログラミングの参考書には次のような文字列が出てくることがあります
foo
,bar
,baz
hoge
,piyo
,fuga
これらのような例示用の意味のない単語を使った変数を「メタ構文変数」と呼びます。 メタ構文変数は実際の仕事のコードなどで書くと、変数が示しているものがなんなのか分かりづらくなるため、基本的には使用しないようにしましょう。
constとletの使い分け
さて変数宣言にはconst
とlet
があることを学びました。
なんとなくlet
の方が再代入もできるので便利そうな気がしますが、実際はどうやって使い分けると良いのでしょうか。
基本的な方針としては次のものを推奨します。
- 基本的には
const
を使う - どうしようも無い場合のみ
let
を使う- (慣れてきたら)
let
を使わなくても良いようにプログラムを工夫する
- (慣れてきたら)
const
を使うと再代入ができません。これを踏まえると例えば文字列や数値や最初に宣言した値が最後まで使われることになります。
let
を使ってしまうと途中でなんらかの処理が挟まると数値が代わってしまう可能性があります。
つまりlet
で宣言された変数を扱う場合、プログラムをよく読んで今何の値が入っているかを注意深く追う必要があります。対してconst
の場合は宣言部分だけ読めばいいので、プログラムを読む上でだいぶ楽になります。
また実際問題として再代入を必要とする処理は、JavaScript/TypeScriptのよい機能を使うとほとんどがconst
での宣言で書けるようになっています。計算した結果を保存する際も、再代入ではなく別名で保存すれば良いわけです。
さらに一見するとlet
を使わざるを得なさそうな処理も、JavaScriptを習得していくにつれて便利な様々な機能を使っていくと、意外とconst
でイケる、となっていきます。
また、実はこの後やるTypeScriptを使う上では特にconst
を使って値が決まっているコト、がとても便利にプログラミングできる体験につながっていきます。
そのため基本的にはconst
を使ってJavaScriptはプログラミングするようにしていきましょう。