JavaScript講座

ユーザ定義関数

関数

関数

特定のコードの流れ(文脈)に依存せず、複数の文脈で使い回せる一連の処理をパッケージングしたものが関数である。

関数は外から呼び出されると、処理を実行し、必要があれば戻り値を呼び出し元に戻す。

関数の構成要素
function 関数名(仮引数1, 仮引数2…){
    処理の中身;
    [return 戻り値;]
}
戻り値の受取
変数 = 関数(引数…);
<script>
function add_num(num1, num2){
    const add = num1 + num2;
    return add;
}
const num = add_num(2,4);
document.write(num);
</script>
/*
 * 合計を求める関数
 * @param Array values (valuesは数値配列)
 * @return Number (戻り値は数値)
 */
function sum(values){
    var result = 0;
    for(var i = 0; i < values.length; i++){
        result = result + values[i];
    }
    return result;
}

変数のスコープ

スコープとは

変数の「寿命」には限界がある。変数は自分が「生まれた」関数を超えては生きられない。

関数の処理内容を記述する{}の中ではじめて定義された変数を「ローカル変数」と呼ぶ。

関数の「引数」はローカル変数とは呼ばないが、ローカル変数と同じ扱いがされる({}の中で定義されたものとして扱われ、関数を超えては生きられない)。

scope.html
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>ローカル変数、引数、グローバル変数</title>
<script>
//関数の外で定義されている変数
var8 = 80;
var9 = 90;

function func(var1){
    var var8 = 0;
    var8 += 8;
    var9 += 9;
    var2 = 2;
    var var3 = 3;
    return var1 + var2 + var3 + var8 + var9;
}
</script>
</head>
<body>
<p>func(1)の実行結果
<script>
document.write( func(1));
// document.write('<p>var1を関数の外で見てみると' + var1 +'</p>');
document.write('<p>var2を関数の外で見てみると' + var2 +'</p>');
// document.write('<p>var3を関数の外で見てみると' + var3 +'</p>');
document.write('<p>var8を関数の外で見てみると' + var8 +'</p>');
document.write('<p>var9を関数の外で見てみると' + var9 +'</p>');
</script>
</body>
</html>
グローバル変数

関数の外で定義された変数は「グローバル変数」である。

関数内部で変数宣言varを付けずに変数を定義するとその変数も「グローバル変数」となる。

グローバル変数は{}の限界を超えて生き続けることができる。

関数の呼び出し

関数を利用する(呼び出す)
関数名(実引数1,実引数2…)

関数に実引数を代入すると関数で定義された処理が具体的に実行され、戻り値があればそれを値として利用できる(別の変数に代入、そのままdocument.write()など)。

returnValue.html
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="initial-scale=1.0">
   <title>戻り値</title>
   <script>
function addition(var1, var2){
    return var1 + var2;
}
   </script>
</head>
<body>
<h1 id="title">戻り値</h1>
<script>
var num1 = 5;
var num2 = 6;
var num3 = addition(num1, num2);
document.write(num3);
</script>
</body>
</html>

値渡しと参照渡し

PassByValue.html
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>関数の呼び出し(値渡し)</title>
<script>
var var1 = 1;                     //関数の外で定義されている変数
var var2 = 10;

function func(var1, var9){   //第一引数は値渡し
    var1 = var1 + var9;     //このvar1は引数で定義されたもの(2行目のvar1とは無関係)
    return var1;
}
</script>
</head>
<body>
<p>var1の中身
<script>
document.write(var1);                   //2行目で定義されたvar1の値を表示
</script>
</p>
<p>func(var1, var2)の実行結果
<script>
var3 = func(var1, var2);    //2行目で定義されたvar1の値(1)をfuncの第一引数に渡している
document.write(var3);
</script>
</p>
<p>var1の中身
<script>
document.write(var1);                  //2行目で定義されたvar1の値を表示
</script>
</p>
</body>
</html>
値渡し

※func関数のローカル変数var1は5になるが、func関数の実引数として渡されたvar1の値は変化しない。実引数として渡されたのはvar1の中身(値)であって、変数そのものではない(「値渡し」)。

※変数そのものを渡す渡し方を「参照渡し」と呼ぶ。

CallByReference.html
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>関数の呼び出し(参照渡し)</title>
<script>
var Object1 = new Object();
Object1.var1 = 1;               //関数の外で定義されている変数
var var2 = 10;

function func(Object0,var9){
    Object0.var1 = Object0.var1 + var9; //このObject0.var1は新たに定義されたもの(8行目のObject1.var1とは無関係)
    return Object0.var1;
}

</script>
</head>
<body>
<p>var1の中身
<script>
document.write (Object1.var1);  //Object1.var1の値を表示
</script>
</p>
<p>func(var1,var2)の実行結果
<script>
var3 = func(Object1,var2);     //Object1.var1の「参照」をfuncの第一引数に渡している
document.write(var3);
</script>
</p>
<p>var1の中身
<script>
document.write(Object1.var1);   //Object1.var1の値を表示(中身が書き換わっている!)
</script>
</p>
</body>
</html>

参照渡し

※JavaScriptにおいては「オブジェクト」は「参照渡し」となる。

※参照渡しされた変数は関数内部での変更が関数外部にも及ぶ。

関数利用の一般的留意点

グローバル変数・参照渡し

関数は特定の文脈から切り離されているが故に利用価値が高まる。しかしグローバル変数や参照渡しを用いるとその独立性が失われる。

従って関数を利用するに当たってはグローバル変数や参照渡しは極力使用しないのが望ましい。