クモのようにコツコツと

フロントエンドエンジニア イイダリョウのブログ。略称「クモコツ」

【JSの基本-前編】書ける前に読む!HTML、CSS、JSの書式-4

Webサイトを形作っている言語「HTML」「CSS」「JS」。
この3言語を身につけるためには、まずはフワッとでもコード*1を読めるようになることが先決と思う。人のコードを読める(インプット)と、自分でゼロから書く(アウトプット)ときの引き出しになる。
書ける前に読む!*2と、いうことでコードを読むために理解しておくといいHTML、CSS、JSの基本書式をまとめる。

第4回は「JSの基本-前編」。Webサイトの動作、変更を制御する「JS」の書式を前・後編に分けてお送りする!

連載一覧:

目次:

第1回(Webの基礎知識)にも書いたようにJSは文書に動作や変更を加える「スクリプト言語」だ。
前・後編に分けてお送りするJS編。前編はその基本となる「オブジェクト」「関数」「変数」について解説する。なお、次回(後編)では「イベント」「制御構造」について解説する。

コメント

前回(CSSの基本)と同様に、JSもまずはコメントから解説する。一部はCSSと共通する書き方だ。
HTML、CSSと同じくJSでもコメントはブラウザ処理で無視される。

/* コメントです。 */

/* 複数行のコメントです。
コメントですったら、
コメントです。 */

// 一行の簡単コメントです。

JSのコメントは2種類の書き方がある。一つはCSSと同じ/*で開始して*/で閉じる。
もう一つ、行頭にスラッシュ2つ//と書くだけで閉じる必要がない1行専用のコメントもある。

オブジェクト、プロパティ、メソッド

オブジェクト指向

JSは「オブジェクト指向*3という考え方で作られたプログラミング言語だ。「オブジェクト」とは対象のことで日本語文でいう「何が」に当たる。オブジェクト指向はオブジェクトとそれに対する「処理」を主軸にしている。
オブジェクトに対する処理には「プロパティ」と「メソッド」がある。「プロパティ」は状態(「どうなる」)で「メソッド」は動作(「どうする」)だ。

  • オブジェクト:対象(例:何が=イイダリョウが)
  • プロパティ:状態(例:どうなる=赤面になる)
  • メソッド:動作(例:どうする=駅に行く)

オブジェクト

オブジェクトは「オブジェクト階層」という階層構造になっている。
先にオブジェクトは「対象」日本語で言う「何が」に当たると書いた。
例えばこの「何」が「東京特許許可局局長」なら中身は「東京都の特許許可局の局長」と階層化されている。
「漢委奴国王印」なら「漢の委(わ)の奴(な)の国王の印(いん)」と階層化されている。

//オブジェクト
オブジェクト.処理;

//オブジェクト階層
オブジェクト.オブジェクト.オブジェクト.処理;
  • ドット.が「の」のような意味になり、オブジェクト同士を繋げて行く。
  • 「オブジェクトのオブジェクトのオブジェクトを処理する」という感じで最後のオブジェクトに続けて処理(プロパティかメソッド)を書く。
  • 行末にはセミコロン;を付ける。前回(CSSの基本)の「プロパティ」「値」部分に似ている。

JSにはいくつかのオブジェクトがあらかじめ用意されている。*4
例:

//オブジェクト階層
window.location.処理;

//(window省略)
location.処理;
  • windowはブラウザ全体を意味するオブジェクト。
  • locationはリンク先を意味するオブジェクト*5
  • windowlocationを処理する」という意味になる。
  • なお、windowsオブジェクトは最上位オブジェクトで、全てのオブジェクトに含まれるため、省略することも可能だ。

プロパティ

プロパティの基本書式は下記となる。

//プロパティ
オブジェクト.プロパティ = 値;

先に書いたようにプロパティは「状態(どうなる)」。 「オブジェクトのプロパティを値にする」という意味になる。
オブジェクトにはいくつかのプロパティがあらかじめ用意されている。

  • オブジェクトの後にドット.でプロパティを繋ぐ。
  • イコール=で繋いだ値をプロパティに代入する。

例:

//プロパティ
window.location.href = "http://idr-zz.hatenablog.com";

//プロパティ(window省略)
location.href = "http://idr-zz.hatenablog.com";

windowオブジェクトのlocationオブジェクトのhrefプロパティ(URL)を"文字列"にする」という意味になる。
ウィンドウが読み込まれた時に、"http://idr-zz.hatenablog.com"のURLにリダイレクト*6を実行する。
値が「文字列」の場合はダブルコーテーション" "で囲う。これは第2回(HTMLの基本)の「属性」や前回(CSSの基本)の「属性セレクタ」と同様だ。

メソッド

メソッドの基本書式は下記となる。

//メソッド
オブジェクト.メソッド(引数);

先に書いたようにオブジェクトは動作(どうする)。 「オブジェクトが引数をメソッドする」という意味になる。
オブジェクトにはいくつかのメソッドがあらかじめ用意されている。

  • オブジェクトの後にドット.でメソッドを繋ぐ。
  • メソッドの後ろにカッコ( )を付ける。前回(CSSの基本)の「CSS関数」と似ている。
  • カッコの中には「引数」*7を入れる。(引数の中身がなくてもカッコは省略しない!)

例:

//メソッド
window.alert("こんにちはッス!");

//メソッド(window省略)
alert("こんにちはッス!");

windowオブジェクトに"文字列"alertメソッドを実行する」という意味。
メソッドもプロパティと同じく値が「文字列」の場合はダブルコーテーション" "で囲う。
ウィンドウが読み込まれた時に文字列"こんにちはッス!"をアラート表示*8する。

プロパティの値の取得

プロパティをメソッドの引数などに単独で入れると、プロパティに入っている値を取得する。

//プロパティの値を取得
オブジェクト.メソッド(プロパティ);

例:

//このページのURLはhttp://idr-zz.hatenablog.comです!
alert("このページのURLは" + location.href + "です!");

上記の例ではalertメソッドの引数の中で"文字列"location.hrefを「算術演算子」*9のプラス+で繋いでいる。
なお、「演算子」とは演算(計算)に使われる記号で他にも様々な種類がある。*10
ウィンドウ読み込み時にlocationオブジェクトのhrefプロパティの値(URL)を取得し、前後の"文字列"と一緒にアラートに表示する。
例えばページのURLが"http://idr-zz.hatenablog.com"の場合は「このページのURLはhttp://idr-zz.hatenablog.comです!」とアラート表示する。

DOM

「DOM」とはDocument Object Modelの略で、ページに表示されている第2回(HTMLの基本)で触れたHTMLの「要素」を「オブジェクト」として指定できる。
いくつかの指定方法がある。

//id名で指定
document.getElementById("id名").処理;

//class名で指定
document.getElementsByClassName("class名").処理;

//タグ名で指定
document.getElementsByTagName("タグ名").処理;

//セレクタ(CSS)名で指定(単独)
document.querySelector("セレクタ名").処理;

//セレクタ(CSS)名で指定(複数)
document.querySelectorAll("セレクタ名").処理;

見ての通りDOM自体はメソッドだが、引数に要素名を書くとその要素を取得して「オブジェクト化」する。
そのため、DOMの後ろに処理(プロパティやメソッド)を続けて書くことができる。

  • DOMの引数の値も「文字列」なのでダブルコーテーション" "で囲う。
  • getElementByIdメソッドは「get element by id」の意味。このように2つ目からの単語の頭を大文字にして繋げることをキャメルケースという*11
  • 注意すべきはgetElementsByClassNameメソッドとgetElementsByTagNameメソッドで、どちらもページ内で要素が複数あり得るため、Elementsと複数形のsが付いている。
  • querySelectorメソッドとquerySelectorAllメソッドは#id.classなど前回(CSSの基本)で触れた「セレクタ」と同じ書式だ。

例:

//セレクタ(CSS)名で指定(単独)
document.querySelector("#aisatsu").innerHTML = "こんにちはッス!";

innerHTMLプロパティは、要素の中身を変えるプロパティ。
documentオブジェクト内のid名aisatsuの要素を取得し、中身を文字列"こんにちはッス!"にせよ」という意味になる。

文字列のコーテーション

値や引数の「文字列」を囲うコーテーションはダブルコーテーション" "でもシングルコーテーション' 'でも構わない。
(実はHTMLもCSSの文字列でもシングルコーテーション' 'は使える)

//ダブルコーテーション
window.alert("こんにちはッス!");

//シングルコーテーション(同じこと)
window.alert('こんにちはッス!');

2種類使える理由はコーテーションを入れ子にすることがあるからだ。

//無問題な入れ子
window.alert("画像タグは<img src='hoge.jpg'>と書きます");

/*コーテーションがダブって
    境界がわからないYo! */
window.alert("画像タグは<img src="hoge.jpg">と書きます");

/*2種類のコーテーションが
   入り混じっちゃってるよYo!*/
window.alert("画像タグは<img src='hoge.jpg">と書きます');

下の2つは間違った入れ子の例。第2回(HTMLの基本)で触れた「ネスト構造」と同じく、入れ子には注意したい。

変数

変数=甲乙丙

記述が増えてくるとだんだん可読性が低くなる。また、同じ内容が分散して書かれていると修正のたびに何か所も直さなくてはならない。 「変数」はこれらの事態を解決してくれる。

身近な例といえば、契約書の頭にある「甲乙丙」が思い浮かぶ。

イイダリョウ(以後、「甲」という)とヤマダ不動産(以後、「乙」という)は下記の賃貸契約を結ぶ。  
甲は乙に逆らってはならない。
乙は甲をなんの前触れもなく契約解除できる。
契約解除されたら甲は即座に出ていry

みたいなアレだ。こうした文書は書式化していて、頭の「甲乙丙」を書き換えれば使いまわせるようになっている。
「変数」もこの「甲乙丙」と良く似ている。

変数の基本形

変数の基本書式は下記のような形である。

//変数
var 変数名 = 値;
  • 行頭に var*12と書く。varはvariable(変化する)の略。
  • 半角スペースを空けて変数名を付ける。なお、名前の付け方は第1回(HTMLの基本)のid名、class名の「命名ルール」に順ずる。*13
  • イコール=で値を繋げ、行末にはセミコロン;を付ける。

変数は先の「プロパティ」とよく似ている。変数は自作プロパティのようなものだ。
例:

//修正前
document.getElementById("title").innerHTML = "はじめまして、イイダリョウと申します!";

//変数設定
var title = document.getElementById("title");
var name1 = "イイダリョウ";  
var hi = "はじめまして、";
var welcome = "と申します!";

//修正後
//はじめまして、イイダリョウと申します!
title.innerHTML = hi + name1 + welcome;

//別の名前追加
var name2 = "ヤマダタロウ"; 
var name3 = "カワタジロウ"; 

//別の名前を表示
//はじめまして、ヤマダタロウと申します!
title.innerHTML = hi + name2 + welcome;  

//はじめまして、カワタジロウと申します!
title.innerHTML = hi + name3 + welcome;  
  • document.getElementById("title")は長いので変数titleに代入している。これで毎回長いオブジェクト名を書かずに済む。
  • 変数name1hiwelcomeにも文字列を代入。
  • さらにこれらの変数をinnerHTMLプロパティの値に代入している。
  • また、変数name2name3には別の名前を代入してみた。この変数を代入したinnerHTMLプロパティには別の名前が表示される。

見た目がとてもスッキリしたし、何度も使いまわせる。変更が生じたときは一箇所打ち替えれば済む。

変数で四則演算

変数の値には「文字列」の他にも様々なデータ型*14が入る。
下記は「数値」と「変数」自体も代入している例。
数値は先ほど出た「算術演算子」を使って四則演算ができる。

var teika = 3000;
var zeiritsu = 1.08;
var goukei = teika * zeiritsu;

//合計は3240円になりまぁす。 
window.alert("合計は" + goukei + "円になりまぁす。" ); 
  • 変数teikaに金額の数値を代入。(「数値」はコーテーション" "不要)
  • 変数zeiritsuに消費税率の数値を代入。
  • さらに変数goukeiに2つの変数と計算式を代入。
  • 変数goukeialertメソッドの引数に代入している。もし税率が変わったら変数zeiritsuの一箇所を直せば良い。

配列

「配列」は一つの変数に複数の値を入れること。

//配列
var 配列名 = [値, 値, 値];

//使用例
window.alert(配列名[添字]);

変数の値の部分に角カッコ[ ]を入れて、その中に値を複数入れる。値はカンマ,で繋ぐ。
呼び出すときは配列名の後ろに角カッコ[ ]を付けて、中に「添字」*15(インデックス番号のこと)を書く。
なお、添字は0から数えるので注意(例えば3番目を呼び出したいときは-1で数えて[2]と書く)。
例:

//配列
var soup = ["醤油", "味噌", "塩"];
var gu =["チャーシュー", "玉子", "ノリ"];

//使用例
//味噌チャーシューラーメンくださぁい。
window.alert(soup[1] + gu[0] + "ラーメンくださぁい。"); 

alertメソッドの引数に、配列soupの添字[1]は2番目の"味噌"が、配列guの添字[0]は1番目の"チャーシュー"が入る。

連想配列

「連想配列」は配列に似ているが、添字ではなく「キー」(項目)に値を入れていく。*16

//連想配列
var 連想配列名 = {キー: 値, キー: 値, キー: 値};

//使用例
window.alert(連想配列名[キー]);

連想配列は波カッコ{ }の中にキー、コロン:、値を入れていく。
読み出すときは配列と同じ角カッコ[ ]だが中身は添字ではなくキーになる。
連想配列は配列数の増減の影響を受けないのでメンテに強い仕組みといえる。
例:

//連想配列
var spec =  {
    "名前": "イイダリョウ", 
    "サイト名": "クモのようにコツコツと",
     "職業": "Webデザイナー"
};

//使用例
//職業はWebデザイナーです
window.alert("職業は" + spec["職業"] + "です");

キーと値が長くなったので改行をした。なんと、前回(CSSの基本)触れた「プロパティ」「値」ととても似た形になっている!*17波カッコ{ }で囲っているのも共通している。
alertメソッドの引数には連想配列specのキー"職業"が入っているので、アラートには"Webデザイナー"という値が表示される。

関数

関数=レシピ

次に、「関数」を紹介する。関数は複数の処理をまとめることができる。

例えば料理をしたことがないバイトに「ラーメン作ってー」と声をかけても「はぁ?ラーメンの作り方なんてオレ知らねぇしっ」という返事しか返ってこない。
少なくとも初回は

お湯を沸かして、具材を切って、麺を茹でて、別でスープを作って、麺が茹で上がったらスープに入れて、具材を上に載せて…

みたいな感じでラーメンのレシピを教えてあげる必要があるだろう。
しかし、2回目からは「ラーメン作ってー」と頼めば「ラーメン一丁!」と気持ちよく応じてくれるはずだ。 「関数」もこの「ラーメンのレシピ」と似ている。

また「麺だけでなく野菜も茹でよう」と作り方を変えたいとき、バイトが10人いたら10回作り方を教えなければならない。
しかしレシピの場所を一か所に決めていれば、そこを直せば済む。
これは先の「変数」と同じメリットになる。

ブロック文

波カッコ{ }で複数の文を囲うと、文をグループ化することができる。これを「ブロック文」という。
前回(CSSの基本)の「プロパティ」「値」や先ほどの「連想配列」に続きここでも波カッコ{ }だ。

//関数定義
function 関数名(引数) {ブロック文}

//関数呼び出し(実行)
オブジェクト.関数名(引数);
  • functionの後に「関数名」を付ける。関数名も先ほどの「変数名」と同じく第1回(HTMLの基本)のid名、class名の「命名ルール」に順ずる。
  • 関数名にの後ろにはカッコ( )が付いて、その中に引数が入る。
  • その後に山カッコ{ }が続き、中には複数の処理が書ける。これを「ブロック文」という。ブロック文の最後にはセミコロン;がつかない。
  • 関数の呼び出しはオブジェクトにドット.関数名(引数)を繋げて行末にセミコロン;

関数は定義するだけでは実行されない。定義と呼び出しが別のため実行のタイミングを制御できる。TVの録画予約をしておくようなイメージだ。
ブロック文は複数の処理をまとめると書いたが、単独の処理でも実行のタイミングを制御したいときは関数化するメリットがある。
関数名呼び出しは先ほどの「メソッド」と良く似ている。関数は自作メソッドのようなものだ。*18

関数の基本形

ブロック文の中身をもう少し詳しく解説する。関数の基本形は下記のような書式である。

//関数定義
function 関数名(引数1, 引数2, 引数3) {
    処理1;
    処理2;
    処理3;
    return 戻り値;  //(省略可能)
}

//関数呼び出し
オブジェクト.関数名(引数1, 引数2, 引数3);
  • 引数は複数書ける。カンマ,で繋げる。また、入れる引数が無い場合もカッコ( )は省略しない。
  • 処理も複数書ける。処理の行末にはセミコロン;を付ける。
  • 最後にはreturn、半角スペース、戻り値を書く。戻り値とは処理の結果のこと。戻り値がない場合はreturnは省略可能。
  • 関数呼び出しのカッコ( )の中には具体的な引数の値を入れる。

例:

//関数定義
function kakunin(name) {
    window.alert(name + "さん、この内容で送信します。宜しいですか?");
    window.alert("本当に送信していいですか?");
    window.alert("最後の確認です。本当にいいんですね?");
}

// 関数呼び出し
//イイダさん、この内容で送信します。宜しいですか?
window.kakunin("イイダ"); 

//ヤマダさん、この内容で送信します。宜しいですか?
window.kakunin("ヤマダ"); 
  • 関数kakuninの中に3つのalertメソッドが入っている。
  • 1つ目のalertメソッドの引数に関数kakuninの引数nameがある。
  • ウィンドウを開くと関数kakuninが呼び出され、アラートが3回連続表示される。
  • 呼び出す際に関数kakuninの引数の値が読み込まれる。(引数がイイダのときはイイダさんヤマダの時はヤマダさん

関数で四則演算

先ほど変数で四則演算を行なったが、関数も「引数」に数値を入れると四則演算ができる。

//関数定義
function tashizan(nmb1, nmb2) {
    var goukei = nmb1 + nmb2;
    window.alert(nmb1 + "足す" + nmb2  + "はズバリ、" + goukei +"でしょう。");
}

// 関数呼び出し
//3足す8はズバリ、11でしょう。
window.tashizan(3, 8); 

//5足す8はズバリ、13でしょう。
window.tashizan(5, 8); 
  • 関数tashizanの中で変数goukeiが引数nmb1nmb2を足す。
  • その下のalertメソッドの引数の中に引数nmb1nmb2、変数goukeiが代入されている。
  • 関数tashizanの引数に38と入れると、呼び出し時に合計値11入りのアラートが表示される。
  • 同様に引数に58と入れると、合計値13入りのアラートが表示される。

Return

Returnで値を戻すと、一つの関数を複数の用途で実行できる。

//関数定義
function tashizan(nmb1, nmb2) {
    var goukei = nmb1 + nmb2;
    return nmb1 + "足す" + nmb2  + "はズバリ、" + goukei +"でしょう。";
}

// 関数呼び出し
//3足す8はズバリ、11でしょう。(アラート)
window.alert(tashizan(3, 8);

// 3足す8はズバリ、11でしょう。(#answerの中身)
document.querySelector("#answer").innerHTML= tashizan(3, 8);
  • 関数内のAlertメソッドにあった引数はReturnの値に移動した。
  • Alertメソッドは外部化してwindowオブジェクトに付けた。引数の中には関数tashizanを入れた 。この形でもアラートが表示される。
  • 新たに#answer"innerHTMLプロパティの値にも関数tashizanを入れた。要素に文字が表示される。

スコープ

関数の中の変数をローカル変数、関数の外の変数はグローバル変数という。
ローカル変数は関数の外から呼び出すことができない。これの変数の適用範囲を「スコープ」という。
スコープは前回(CSSの基本)触れた「セレクタの優先順位」と同じくとても重要な概念だ。

//関数定義
function tashizan(nmb1, nmb2) {
    var goukei = nmb1 + nmb2;  //ローカル変数
    return nmb1 + "足す" + nmb2  + "はズバリ、" + goukei +"でしょう。";
}

// 関数呼び出し
//3足す8はズバリ、11でしょう。
//アラート
window.alert(tashizan(3, 8));

//ローカル変数呼び出し
//実行されない!
//アラート
window.alert("合計はズバリ、" + goukei +"でしょう。"); 

先ほどの「関数2」の箇所をローカル変数goukeiを呼び出すアラートに変更。一見上の「関数実行」とアラートよく似ている。
しかし変数goukeiはスコープから外れるので実行されない! *19

無名関数

「無名関数」とは関数名がない関数。一度切りの使い捨て関数として良く使われる。*20 下記のようにfunctionの後に関数名がなく、すぐに引数のカッコ( )が続く。

//無名関数
function (引数) {ブロック文}

ただし、このままだと実行する名前がないので動かない。

先ほどの例の関数名と同じ変数を作って、関数は無名関数化する。 なお、変数の値に関数を入れると変数が「メソッド化」して引数を持つ。

//function tashizan(nmb1, nmb2) { 
//変数tashizanに無名関数を入れる(変数がメソッド化)
var tashizan = function (nmb1, nmb2) {
    var goukei = nmb1 + nmb2;
    window.alert(nmb1 + "足す" + nmb2  + "はズバリ、" + goukei +"でしょう。");
}

// メソッド呼び出し
window.tashizan(3, 8); 

見た感じ関数名と変数名が入れ替わっただけでほとんど違いがないようだ。
変数がメソッド化したので、下の実行コードも全く変わらない。そして挙動も変わらない。
今回は実行上名前が必要だったために関数名を変数名にした格好だが、次回(後編)に触れる「イベント」ではこの無名関数が活躍する。*21

さあ、徐々にJSの「何が、どうなる」がわかりかけてきているのではないだろうか。
次回はさらに「いつ」「もし○○なら」などを制御をする「イベント」「制御構造」の解説する!

※次回: 【JSの基本-後編】書ける前に読む!HTML、CSS、JSの書式-5 idr-zz.hatenablog.com


本連載は、これからWebサイト制作を始めてみたい方を念頭に、当ブログの記事中に出てくるWeb系の単語の「出発点」になることを目指して書きました。
なるべく平易な言葉で、段階的な説明を心がけたつもりです。(書きながら自分自身の復習にもなりました)
もし内容に不明点、おかしい点などあれば(優しく)ご指摘いただけると幸いです。


※参考:HTML、CSS、JSの書式まとめました!
【HTML、CSS、JSの書式】これを読めばコードが読める!書ける!まとめ!(基本5+応用1記事) - クモのようにコツコツと idr-zz.hatenablog.com

※参考:【HTML、CSS、JSの書式】まとめ
qiita.com

*1:ソースコード。人が書いたコンピュータへの命令のこと。

*2:某胃腸薬

*3:他に「手続き型」「関数型」などもある

*4:組み込みオブジェクト、ブラウザオブジェクト、DOMオブジェクト、Ajaxオブジェクトなどがある。

*5:実際のオブジェクトは一文字目が大文字で、コードに書かれているのはオブジェクトを呼び出しているプロパティ…などの説明は今回は省略

*6:サイトのお引越しでよくある、自動的にページを切り替えるやつね。

*7:「ひきすう」と読む。「いんすう」ではないので注意!

*8:ブラウザの手前に小窓で出てくるメッセージのやつね。

*9:算術演算子には四則演算の+-*/などがある。

*10:比較演算子(<=, >=, == 他)、論理演算子(&&, ||, !)など。これまで出てきたドット(.)、イコール(=)や並列のカンマ(,)なども演算子の一種。

*11:他にアンダースコア「_」で繋ぐスネークケースもある

*12:他にvarより厳密な方の「let」「const」もある。

*13:「予約語」という使えない単語もある

*14:データの種類のこと。文字列、数値、関数、真偽値などがある。

*15:「そえじ」と読む。

*16:配列と連想配列はHTMLのリストのol要素(番号付き)、dl(項目付き)の関係と似ている。

*17:そしてJSON(ジェイソンと読む)というデータ形式にも似ている、というか全く同じ!JSONはJavaScript Object Notationの略なので。

*18:JSの機能を拡張するライブラリ(jQuery、reactなど)やフレームワーク(angularなど)は関数で独自のメソッドを定義している。

*19:ちなみに先の「変数」にあった例はすべて関数の外で定義されているので、グローバル変数だ。

*20:似た関数で「即時関数」もあるが今回は省略

*21:無名関数は関数を雛形化する「コンストラクタ」にも使われる。今回は触れないが雛形化にはclass構文という書式もあり、そちらの方がシンプル。