5日目:変数 (val) と 配列 (array) を理解しよう。 – 1週間でプログラマーになろう。(毎日30分のプログラミング学習、入門講座)

1週間でプログラマーになる実践講座、5日目の画像 プログラミング講座
cattle
cattle

本日は変数と配列について学んで行きましょう。この講座を終えると、プログラムに対する理解度がググッとアップします。なんとなくよくわからなかったモヤモヤ感が解消され、プログラマーとして機械を思い通りに操れる様になります。

途中からご覧になった方は、全体のロードマップをご確認頂けます。

わからない所があれば、ページ下部のコメント欄、又はtwitterからご相談頂けます。

5日目:変数 (val) と 配列 (array) を理解しよう。 – 1週間でプログラマーになろう。(毎日30分のプログラミング学習、入門講座)

前半(15分)- 変数 (val) の仕組みを捉えよう。

前半部分は、主に絵を見ながら想像力を活用していきます。是非、お茶やコーヒーなど飲みながら、リラックスしてお楽しみください。

変数の名前(3分)

「変数の名前」とは、現実世界の「都道府県」の様な物です。

変数の名前解説の画像

都道府県は、抽象的な表現です。
ある時、東京都のとある地域が、埼玉県に吸収される事になったとします。それでも私達は、これまで通り東京都、埼玉県と表現して、それぞれの正しい領域を指し示すことが出来ます。変化に柔軟な表現方法は、プログラミングの世界においても非常に都合が良いのです。

これを、変数に置き換えて想像すると、以下の様になります。

function japaneseLand() {
  val tokyo = '新宿';
  val saitama = '川越';
  val hokkaido = '札幌';
}
変数の名前解説画像

パソコンの記憶領域の大きさには限りがあります。変数も同様に、記憶領域の大きさが定められています。(JavaScriptでは、変数に割り振られる領域の大きさを、必要に応じて機械が自動的に広げてくれます。)

– データの構造化は、配列で行いましょう。
渋谷、熊谷、登別のデータが無くなっている事に気づいた方は、大変素晴らしい着眼点をお持ちです。これに関しては、後半に学ぶ「配列」という仕組みを利用すると、一つの変数で気持ち良く複数のデータを管理出来る様になります。

変数の中身は、常にアドレス(6分)

– 変数は、値を直接保存していません。記憶領域を間接的に指し示します。

変数の名前解説画像

上の図を見ながらじっくりと想像してみて下さい。tokyoという変数には、パソコンの記憶領域の「ここからここまで」を使いますよ、という情報のみが格納されている事がわかります。変数saitama、変数hokkaidoも同様です。

例えば、以下のコードで、japaneseLand関数を実行します。

function japaneseLand() {
  var tokyo;
  tokyo = '新宿';
  console.log(tokyo);
}
ログの画像

1.変数tokyoを用意しました。
2.変数tokyoに’新宿’という文字列を代入しました。
3.(変数tokyoに、’新宿’文字列データが保存された記憶領域のアドレスが格納されました。)

変数のフローチャート画像

4.console.log関数で、変数tokyoを呼び出しました。
5.(変数tokyoの中に格納されている「アドレス」を元に、パソコンの記憶領域にアクセスします。)
6. 5の結果、’新宿’という文字列データを見つける事が出来たので、console.log関数は、’新宿’という文字列をログに表示しました。

変数のフローチャート画像

– 変数の中身は、常にアドレス
小難しいお話でしたが、変数の値が参照される流れを掴めると、プログラマーとして一気にレベルアップします。この仕組みは「ポインタ」と呼ばれ、数多くのプログラミング初心者を挫折に追い込みました。(私も挫折した内の一人でしたが、「変数の中身は、常にアドレス」と繰り返し呪文を唱える事で、なんとか壁を乗り越える事が出来ました。)

変数の型(1分)

– 後半に学ぶ配列も「変数の型」のひとつ
JavaScriptは、型を意識せずに扱えるようになっています。しかし、今後より高度なプログラミングに挑んで行く際には、変数の型をよく理解している必要があります。特に、エラーが起きた際に対処(デバッグと呼びます)する力が格段に変わってきます。

JavaScriptの変数は、どんな型であってもvarで宣言する事が出来ます。

var number = 100;  // 数値型の値を変数numberに代入
var string = 'モゥモゥ';  // 文字列型の値を変数stringに代入
var boolian = true;  // 論理型の値を変数boolianに代入

以下の様に、数値を文字列型として扱う事も出来ます。

var string = '100';  // 文字列型

変数を使った演算(5分)

以下の様に、変数を使って四則演算(しそくえんざん)を行う事が出来ます。

var price = 100
console.log(price + 10);  // 足し算は + で行います。
console.log(price - 5);   // 引き算は - で行います。
console.log(price * 2);   // 掛け算は * で行います。
console.log(price / 4);   // 割り算は / で行います。

変数同士で演算を行うと、より変化に強いプログラムが構築出来ます。

var price = 100
var tax = 0.08;  // 消費税率8%

// 数学と同様に、演算は掛け算が優先されます。
var priceIncludingTax = price + price * tax;
console.log(priceIncludingTax);  // 税込み価格

機能ごとに関数化すると、より実用的なプログラムコードとなります。

// 税込み価格を取得する関数
function getPriceIncludingTax(price) {
  tax = 0.08;
  return price + price * tax;
}

function mainProc() {
  var apple = 120;
  var orange = 140;
  var melon = 4000;

  console.log(getPriceIncludingTax(apple));
  console.log(getPriceIncludingTax(orange));
  console.log(getPriceIncludingTax(melon));
}

異なるデータ型同士で演算を行うと、プログラマーの意図しない動作に成り得ますのでご注意下さい。以下は、数値型の値に対して、文字列型の値を足しています。

function mainProc() {
  var num = 100;
  var str = '2';

  var result = num + str;
  console.log(result);
}
ログの画像

上記の演算を、数値同士として扱って欲しい時は、文字列型の値を、数値型の値に変換しましょう。データ型を異なる型に変換する行為を Cast (キャスト) と呼びます。

function mainProc() {
  var num = 100;
  var str = '2';

  var result = num + Number(str);
  console.log(result);
}
ログの画像

Number( ) は、JavaScriptが予め用意してくれている便利なキャスト機能です。余談として、数値型を文字列型として扱い時は、String( ) という機能を使います。

cattle
cattle

お疲れさまでした。前半はここまでです。変数の中には常にアドレスが入っている、と意識して行きましょう。後半からは配列を扱っていきますので、早速このイメージが役に立ちます。

後半(15分)- 配列 (array) を使ってみよう。

まずは実際に使ってみましょう(5分)

スクリプトエディタに以下のコードを記述して、mainProc関数を実行してみましょう。

配列の宣言をする時は、 [ ] で囲みます。※ Enterキー左側にある2つのキーで開き括弧と閉じ括弧を記述出来ます。{ }と間違えない様にご注意ください。

function mainProc() {
  var tokyo;
  tokyo = ['新宿', '渋谷', '秋葉原'];
  console.log(tokyo);
}
ログの画像

次に、コードを以下の様に修正して、再びmainProc関数を実行してみましょう。

function mainProc() {
  var tokyo = ['新宿', '渋谷', '秋葉原'];
  console.log(tokyo[2]);
  console.log(tokyo[0]);
  console.log(tokyo[1]);
}
ログの画像

コードの途中で、配列の値を操作してみます。どうなるでしょうか。

function mainProc() {
  // 配列を定義して、変数に代入
  var tokyo = [
    '新宿',   // 縦書きも出来る。
    '渋谷',   // ,(カンマ)で区切っていく
    '秋葉原'  // 最後は,(カンマ)不要
  ];
  console.log(tokyo);

  // 末尾に追加
  tokyo.push('上野');
  console.log(tokyo);

  // 秋葉原を高田馬場に変更
  tokyo.splice(2, 1, '高田馬場'); 
  console.log(tokyo);

  // 先頭に追加
  tokyo.unshift('品川');
  console.log(tokyo);
}
ログの画像

配列の仕組みをイメージで捉えましょう。(5分)

配列の中に存在する複数の値は、それぞれ要素と呼ばれます。

var 変数の名前 = [要素の値, 要素の値, 要素の値];

// カンマ後のスペースは、有り無しどちらでもOK
var tokyo = ['新宿','渋谷','秋葉原'];

// 数値もOK、変数もOK
var number = 500;
var price = [100, number, 50];

以下のプログラムコードを例に、図解して行きます。

function mainProc() {
  var tokyo;
  tokyo = ['新宿', '渋谷', '秋葉原'];
  console.log(tokyo);
  console.log(tokyo[2]);
  console.log(tokyo[0]);
}
ログの画像

変数tokyoを用意します。全ての要素をパソコンの記憶領域に保持します。変数tokyoの中に各要素のアドレスを格納します。

配列のフローチャート画像

配列が納められた変数を呼び出すと、以下の様に配列全体の値が戻ってきます。

配列のフローチャート画像

配列の要素は、先頭を0と表現し、1、2、・・・と続きます。この番号をインデックス (index)と呼びます。今回は、変数tokyoに含まれている配列の要素、インデックス2を呼び出しています。

配列のフローチャート画像

以下は、前回とほぼ同様です。インデックス0を呼び出しています。

配列のフローチャート画像

最後に、複数の配列が存在する例を見てみましょう。機械の気持ちが少し分かる様になります。

function mainProc() {
  var tokyo;
  tokyo = ['新宿', '渋谷', '秋葉原'];
  console.log(tokyo);
  console.log(tokyo[0]);

  var saitama;
  saitama = ['川越', '熊谷'];
  console.log(saitama);
  console.log(saitama[0]);

  var hokkaido;
  hokkaido = ['札幌', '登別'];
  console.log(hokkaido);
  console.log(hokkaido[0]);
}
ログの画像
配列のフローチャート画像

上の図の様に、単純に saitama[0] , hokkaido[1]などと呼び出すだけで、欲しい値に簡単にアクセスできる仕組みになっています。

配列の値渡し、参照渡し(2分)

配列の中身をまるごとコピーしたいと思った時は、以下のコードでコピーできます。

  var tokyo = ['新宿', '渋谷', '秋葉原'];  
  var tokyoCopy = tokyo;

コピーした配列内容に修正を加えると、コピー元の配列内容にも、影響を及ぼします。これを配列の参照渡しと呼びます。

function mainProc() {
  var tokyo = ['新宿', '渋谷', '秋葉原'];
  console.log('tokyo', tokyo);
  
  var tokyoCopy = tokyo;
  console.log('tokyoCopy', tokyoCopy);
  
  console.log('--- tokyoCopyの内容を修正 ---');  
  tokyoCopy[0] = 'モゥモゥ牧場';
  console.log('tokyo', tokyo);
  console.log('tokyoCopy', tokyoCopy);  
}
ログの画像

(繰り返しになりますが、変数に保存されているのは、実際の値ではなく、記憶領域のアドレスです。このアドレスがコピーされているので、参照先を共有しています。)

アドレスを共有せずに(共通の記憶領域を共有せずに)配列をコピーするには、以下の様にsliceを使います。これを、配列の値渡しと呼びます。

var tokyo = ['新宿', '渋谷', '秋葉原'];
var tokyoCopy = tokyo.slice(0, tokyo.length);
function mainProc() {
  var tokyo = ['新宿', '渋谷', '秋葉原'];
  console.log('tokyo', tokyo);
  
  var tokyoCopy = tokyo.slice(0, tokyo.length);
  console.log('tokyoCopy', tokyoCopy);
  
  console.log('--- tokyoCopyの内容を修正 ---');  
  tokyoCopy[0] = 'モゥモゥ牧場';
  console.log('tokyo', tokyo);
  console.log('tokyoCopy', tokyoCopy);  
}
ログの画像

記憶領域には’新宿’, ‘渋谷’, ‘秋葉原’という配列データが保持されているわけですが、参照渡しは単純にこの一つの配列データを共有しています。値渡しの場合は、記憶領域に全く別の新しい’新宿’, ‘渋谷’, ‘秋葉原’という配列データを作ります。

オブジェクト (object) を知ろう。(3分)

以前、console.logは関数である、と解説しました。これを更に深掘りすると、consoleはオブジェクトと呼ばれる物です。cosoleオブジェクトは様々な機能/パラメータの集合体であり、log関数はその一部です。オブジェクトの持つ機能を呼び出すには、以下の文法を用います。

オブジェクト.(ドット)関数名
オブジェクト.(ドット)パラメータ名  // 変数名とも解釈出来ます

またJavaScriptでは、配列もオブジェクトとして管理されています。[ ]で定義した配列を変数に代入すると、その変数は自動的に「配列オブジェクト」となります。

// 配列を代入する事で、変数tokyoは配列オブジェクトとなる。
var tokyo = ['新宿', '渋谷', '秋葉原'];  

// 配列オブジェクトは、専用の便利な機能(関数)にアクセスできる。
tokyo.push('上野');  // 引数を渡すと、配列末尾に新しい要素が追加される。
tokyo.unshift('品川');  // 引数を渡すと、配列先頭に新しい要素が追加される。
// 引数をチューニングする事で、追加、修正、削除など汎用的に使える。
tokyo.splice(2, 1, '高田の馬場');

オブジェクトのパラメータは、そのオブジェクトが持つ固有の情報です。配列オブジェクトには length という固有パラメータが存在しており、自分が持つ要素の個数を管理しています。

var tokyo = ['新宿', '渋谷', '秋葉原'];
console.log(tokyo.length);
ログの画像

オブジェクトは、簡単に作る事が出来ます。そして、簡単に扱えます。キーと値をセットにして定義して行くので、連想配列とも呼ばれています。

var obj = {キー: 値, キー: 値, キー: 値 ・・・};  // : (コロン)でキーと値をセットにする。
function mainProc() {
  // オブジェクトの定義
  var cow = {name: '生まれたての子牛', age: 0};

  console.log(cow);
  console.log(cow.name);
  console.log(cow.age);
  
  // オブジェクトに新しいkeyを追加
  cow.voice = 'モゥモゥ';

  // 貴方のオリジナル関数
  function growUp(obj) {
    obj.age++;
    console.log('------');
    console.log(obj.voice);
    console.log(obj.age);
  }

  // forループでうしを育成しましょう。
  for(var i=0; i<3; i++) {
    growUp(cow);  // すくすく成長
  }
}
ログの画像

– JavaScriptの更なる上達のコツ
JavaScriptが予め用意してくれている便利な機能群(関数群)、パラメータ群を積極的に使って行く事で、よりスマートにプログラムを組める様になります。関数の内側の仕組みが完全にわからなくても、「その関数は何が出来るのか」、「引数は何を渡せばよいのか」、「戻り値として何が得られるのか」の3つさえ理解できれば正しく扱えます。是非Google検索エンジンをフル活用して、javascriptの持つ素晴らしい拡張性、柔軟性をより味わっていきましょう。

cattle
cattle

本日はここまでです。おつかれさまでした。これまでの5日間は、ひたすらJavaScriptを学んで来ました。今後の2日間は、実際に皆さんが学んだ事を活かして、自分のプログラミングを書いて行きます。

わからない所があれば、ページ下部のコメント欄、又はtwitterからご相談頂けます。

本日のまとめ

・変数の仕組みを、より具体的に想像出来る様になりました。

・配列によって、情報を構造的に扱えるようになりました。

・今後も必要に応じて、調べながら勉強を継続して行きましょう!

次回、実践ゲーム!問題を解いてみよう。

コメント