プログラミング講座 第2回

第2回の目標:javascriptの基本的な文法をもう少し確認する。

1.繰り返し(while)

while文でも繰り返す処理を行える。

whileに続く丸括弧の中に繰り返しが続行されるための条件を書く。下記の例では、変数iの値が10より小さいあいだ、3行目と4行目が繰り返し実行される。3行目のconsole.log(i)は変数iの値をコンソールへログとして表示する命令である。4行目のi++を行わないと無限ループに陥るため、注意が必要である。

    i = 0;
    while (i < 10) {
      console.log(i);
      i++;
    }
  

フローチャートで表すと以下である

graph TB A([開始]) B[i=0] C{i<10} D[iの値を表示する] E[i++] F([終了]) A --> B B --> C C -->|yes| D D --> E E --> C C --->|no| F

例題1 変数xへ0を代入せよ。その後、while文を用いて変数 x へ 0 から 9 までの値を順に足せ。

結果:

2.配列の操作

一つの変数が1個の箱だとすると、配列は箱がいくつか並んだものである。

配列の何番目のデータであるかを指定することで、データにアクセスできる。何番目のデータであるかを指定する際には、0から数え始めることに注意する。下記の例では、変数xに配列fruitsの0番目のもの(つまり"バナナ")を代入している。

  fruits = ["バナナ", "りんご", "みかん"];
  x = fruits[0];
  

配列の長さとは、配列を箱が並んだものと見たときの並んだ箱の個数である。配列名.lengthで参照できる。下記の例では変数xに配列fruitsの長さ(つまり3)を代入している。

  fruits = ["バナナ", "りんご", "みかん"];
  x = fruits.length;
  

配列の内容を後から変更することもできる。下記の例では配列fruitsの1番目を"柿"にしている。つまり、配列fruitsは["バナナ", "柿", "みかん"]になる。

  fruits = ["バナナ", "りんご", "みかん"];
  fruits[1] = "柿";
  

長さが0の配列を用意することもできる。

  fruits = [];
  

配列の長さを増やすような変更も可能である。下記の例では、配列fruitsは["バナナ", "りんご", "みかん","すいか"]になる。

  fruits = [];
  fruits[0] = "バナナ";
  fruits[1] = "りんご";
  fruits[2] = "みかん";
  fruits[3] = "すいか";
  

これらの例でみたように、配列を扱うときは大括弧や角括弧といわれる[と]の記号を使う。

例題2 配列flowerを用意し、値が0番目から順に"ばら","たんぽぽ","すみれ","さくら"になるようにせよ。

結果:

3.繰り返しの処理と配列の操作

繰り返しの処理と配列は相性が良い。配列の各データを順に読み取ったり設定したりすることができるからである。下記の例では、配列numbersに0か9までの数を設定している。

  numbers = [];
  for (i = 0; i<10; i++) {
    numbers[i] = i;
  }
  

例題3 配列oddNumberを用意し、1,3,5,・・・と奇数を小さい順に10個格納せよ。

結果:

4.関数

数学と同じように関数を利用できる。

  function triangleArea(side, height) {
    return side * height * 0.5;
  }

  myTriangle = triangleArea(5, 8);
  console.log(myTriangle);
  

上の例では、1~3行目でtriangleAreaという関数を定義している。関数を定義するタイミングでは、関数の中身の処理は実行されない。5行目でtriangleArea関数を呼び出しており、このとき初めて関数の中身である2行目の命令が実行される。つまり、パラメータの辺(side)と高さ(height)から三角形の面積を計算して返す。

2行目で使われているreturnの命令は関数内での計算結果を関数の呼び元に返すものである。return命令を書き忘れると計算結果が捨てられてしまうので注意が必要。上の例ではreturnされた面積の値はmyTriangle変数に格納され、6行目でコンソールに20と表示される。

  function showWarning(str) {
    console.log("warning!!" + str);
    return;
  }

  showWarning("何度か");
  showWarning("関数を");
  showWarning("呼びます");
  

必要がなければ関数は値を返さなくてもよい。上の例では、1~4行目でshowWarningという関数を定義している。この関数はstrというパラメータを引き受けるが、特になにも返却しない(3行目のreturnの後に何も指定していないことに注目)。なおこれを実行するとコンソールに以下の内容が表示される。

 warning!!何度か
 warning!!関数を
 warning!!呼びます
  
  function isOddNumber(checkTarget) {
    if ( checkTarget % 2 == 0 ) {
      return false;
    } else {
      return true;
    }
  }

  if(isOddNumber(varX)) {
    いろいろな処理
  }
  

上の例で、関数isOddNumberは1つのパラメータを受け取る(1行目)。それがcheckTargetである。関数へ渡すパラメータを決めるのは関数を呼ぶ側である。関数へ渡されるパラメータの値は関数が呼ばれるときにならないと分からない。

isOddNumberを呼ぶ人はパラメータを渡す。上の例だと9行目である。このとき、varXの値がcheckTargetの値として設定される。

例題4 入力\(x\)に対して\(x^2 - 3x + 4\)を出力する関数myMathを定義せよ。

結果:

5.変数のスコープ

変数のスコープとは変数の有効範囲である。

  {
    let variableA;

    variableAを用いた色々な処理
  }
  ここでvariableAを使おうとするとエラー
  

{と}に囲まれた範囲をブロックという。上記では1行目から5行目が1つのブロックである。ブロック内でletを用いて定義された変数は、そのブロック内でのみ有効であり、ブロック外からアクセスするとエラーが起きる。 このようなスコープをブロックスコープという。関数やif文などでもブロックはつくられる。

  function funcX(){
    let variableA;

    variableAを用いた色々な処理
  }

  function funcY(){
    let variableA;

    variableAを用いた色々な処理
  }
  

通常1つのブロックに同じ名前の変数は1つのみ許されるが、上記のように別々のブロックであれば、それぞれで同じ名前の変数が使える。

  let variableA;

  function funcX(){
    variableAを用いた処理ができる
  }

  function funcY(){
    variableAを用いた処理ができる
  }

  variableAを用いた処理ができる
  

上記のように、すべてのブロックの外側で変数を宣言すると、すべての箇所からこの変数にアクセスできる。このようなスコープをグローバルスコープという。

スコープが広いと変数の動きを把握しにくいため、変数のスコープはなるべく狭くするのがうまいプログラムを作るコツである。

  function funcX(){
    var variableA;

    variableAを用いた色々な処理
  }
  

上記のようにletでなくvarを使った変数の宣言もできるが、これは古い書き方なのでしてはいけない。

  function funcX(){
    variableA; (let を忘れた!!)

    variableAを用いた色々な処理
  }

  function funcY(){
    variableAを用いた処理をするかも知れない
  }
  

上記のようにletを書き忘れると、変数がグローバルスコープ持つことになり、思わぬ挙動をする可能性があるので注意が必要である。

例題5 2つのパラメータ(整数)を受け取り、1つめのパラメータの値から2つめのパラメータの値までを足した値を返す関数myAddを作れ。例:myAdd(5,7)を呼ぶと18が返る。ただし、2つめのパラメータの値が1つめのパラメータの値より大きくない場合は、-1を返せ。

結果:

6.インデント

ブロックの中身にはインデント(字下げ)を施す。インデントは半角スペース2個や半角スペース4個やtabを使う。(いくつかの流儀がある)。javascriptは半角スペースやtabを無視するので、プログラムとしてはインデントは特に意味はなく、人間がプログラムを見やすくするための工夫である。全角スペースは使ってはいけない

  function funcX(height, width){
    let squareArea;
    let Message;

    squareArea = height * width;

    if (squareArea > 100) {
      Message = "this is big square";

      if (squareArea > 1000) {
        Message = "this is very big square";
      }
    } else {
      Message = "this is small square";
    }

    さまざまな処理
  }
  

上の例では、2~17行目は関数のブロックの中であるので、全体的にインデントされている。ここでは半角スペース2個を使っている。8~12行目、14行目はif文のブロックの中なので、そこからさらにインデントされている。11行目はその中のif文のブロックの中なので、さらにさらにインデントされている。

javascriptの文法としては{}がブロックを表すが、プログラマは普通インデントのレベルでプログラムの構造を見るためインデントは正確に行うのがよい。他の言語、例えばpythonではインデントが文法の一部であり、インデントでブロックを表す。

第1.5回へ 目次へ 第3回へ