ファーストクラスオブジェクトとしての関数
【開発環境】
OS;Window10
Webブラウザ:Google Chrome
テキストエディタ:Brackets
◆ファーストクラスオブジェクト
JavaScriptの関数は、変数に代入したり、関数の引数にしたり、更には関数を返すことが可能である。そのような事が出来る値の事を、
ファーストクラスオブジェクト
と呼ぶ1)関数を変数に代入してみる
・例文1
//無関数を変数myFunc1に代入する
var myFunc1 = function(){
console.lon("Hello");
};
//無関数の呼び出し
myFunc1();
・例文2
function myFunc2(){
console.log("Hello");
}
var myFunc3 = myFunc2;関数myFunc2()を変数myFunc3に代入
myFunc2();
myFunc3();
2)関数を別の関数の引数に渡す
JavaScriptでは、関数を、別の関数の引数として渡す事が出来る。
例えば、イベントリスナーを登録するaddEventListener()メソッドでは、リスナー関数(コールバック)として、関数を引数に渡していた。
//リスナー関数
function clickListener1(ev){
~
}
//リスナー登録
myBtn.addEventListener("click",clickListener1,false);
3)関数の内部で関数を定義する
JavaScriptでは、関数内で関数を定義出来る。つまり、関数を入れ子に出来る。
例文
日本語か、英語で曜日を返す関数を作成する
サンプルスクリプト
<!DOCTYPE html>
<html lang="ja">
<head>
<meta>
<title>JavaScriptのテスト</title>
</head>
<body>
<script>
//外側のgetDayStr()関数を定義する
function getDayStr(isJa) {
var today = new Date();
// 日本語で曜日を返す→入れ子
function jaDay(){
var days = ["日", "月", "火", "水", "木", "金", "土"];
return days[today.getDay()];
}
// 英語で曜日を返す→入れ子
function enDay(){
var days = ["Sun", "Mon", "Tue", "Wed", "Thu","Fri", "Sat"];
return days[today.getDay()];
}
//getDayStrの引数で日本語なのか、英語なのか、決めている。
if (isJa) {
return jaDay();
} else {
return enDay();
}
}
//カーソル表示
console.log(getDayStr(true));
console.log(getDayStr(false));
</script>
</body>
</html>
・実行結果
◆スコープチェーン
JavaScriptは変数を参照するときに、同じ関数内に目的の変数が定義されていないかを探す。見つからなかった場合、今度は親関数の中を探す。それでも見つからない場合はさらに親の関数内を探し、最終的にはグローバルスコープまで探しにいく。最後に見つからなかった場合は、undefinedを返す。
このように変数を参照することを、スコープチェーンと言う。
・サンプルプログラム
<!DOCTYPE html>
<html lang="ja">
<head>
<meta>
<title>JavaScriptのテスト</title>
</head>
<body>
<script>
var v1 = "GlobalValue1";③
var v2 = "GlobalValue2";
var v3 = "GlobalValue3";
//外側の関数
function outerFunc() {
var v2 = "OuterValue";②
//内側の関数
function innerFunc() {
var v3 = "InnerValue";①
console.log("v1: " + v1);→グローバル変数
console.log("v2: " + v2);→外部ローカル変数
console.log("v3: " + v3);→内部ローカル変数
}
// 内側の関数を呼び出す
innerFunc();
}
// 外側の関数を呼び出す
outerFunc();
</script>
</body>
</html>
・結果表示
スコープチェーンより、内側の関数のローカル変数→外側の関数のローカル変数→グローバル変数の順に検索される。
◆関数を返す関数を定義する
関数はファーストクラスオブジェクトですので、関数を返す関数を定義することも出来ます。つまり、関数内部で条件に応じた関数を作成して、return文でそれそれを返すことが出来る。
・サンプルプログラム
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>JavaScriptのテスト</title>
</head>
<body>
<script>
//外部関数
function getKuji(isHappy) {
var kujis;→ローカル変数
//if文、配列に値を代入する
if (isHappy) {
kujis = ["大吉", "大吉", "吉", "大吉"];
} else {
kujis = ["吉", "凶", "凶"];
}
//内部関数
function kuji() {
var rnd = Math.floor(Math.random() * kujis.length)
return kujis[rnd];→返し
}
return kuji;→返し
}
// 結果がよいくじ
var kuji = getKuji(true);
console.log("*ハッピーなおみくじ");
for (var i = 0; i < 5; i++){
console.log(kuji());
}
// 結果が悪いくじ
var kuji = getKuji(false);
console.log("*アンハッピーなおみくじ");
for (var i = 0; i < 5; i++){
console.log(kuji());
}
</script>
</body>
</html>
・実行結果
◆関数の再帰呼出し
JavaScriptには、関数内から自分自身を呼び出す、再帰呼出しがある。ただし、そのまま呼び出すと、無限ループに陥る為、if文を併用する。
・カウントダウンの例文
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>JavaScriptのテスト</title>
</head>
<body>
<script>
function countDown(num) {
console.log(num);
if (num == 0) return;
num--;
// 自分自身を呼び出す
countDown(num);
}
countDown(10);
</script>
</body>
</html>
・実行結果
※コメント投稿者のブログIDはブログ作成者のみに通知されます