JavaScriptはじめました(基本的言語仕様 その2)
今回はこんな感じ。
- ブロックスコープはJavaScriptには存在しない。
- argumentsオブジェクト
- 引数のデフォルト値を設定する
- 可変長の引き数を扱う関数
- 名前付き引数
- 高階関数
- クロージャ
- ブロックスコープはJavaScriptには存在しない。
【java】
if (1 == 1) { var n = 123; } document.write(n); //エラーになる
if (1 == 1) { var n = 123; } document.write(n); //123
- argumentsオブジェクト
JavaScriptでは関数の引数が多くても、エラーにはならず、argumentsオブジェクトに格納される。
argumentsオブジェクトは、関数呼び出しのタイミングで生成され、引数の値をすべて保持する。
下の例では・・・
showMessage(123); ⇒123
showMessage(123,456);⇒123と456
がargumentオブジェクトに格納される。
function showMessage(txt) { document.writeln(txt); } showMessage(); //undefined showMessage(123); //123 showMessage(123, 456); //123 //456もargumentオブジェクトに格納される
引数のチェックをかけるためには、arguments.lengthを使う。
function showMessage(txt) { if (arguments.length != 1) { throw Error(’引数の数が違います’+arguments.length); } document.writeln(txt); } try { showMessage(); //エラー showMessage(123); //OK showMessage(123, 456); //エラー } catch (e) { window.alert(e.message); }
- 引数のデフォルト値を設定する
Javascriptでは、引数の指定をしなくてもよいため、引数の指定が行われなかった場合のデフォルト値を設定しておくことが一つの手段としてある。
function triangle(base, height) { if (base == undefined) { base = 1; } if (height == undefined) { height = 1; } return base * height / 2; } document.writeln(triangle(5)); //2.5 heightが省略されていると見なされる document.writeln(triangle()); //0.5
- 可変長の引き数を扱う関数
arguments.lengthをうまく使う。
function sum() { var result = 0; for (var i=0; i < arguments.length; i++) { var temp = arguments[i]; if (isNaN(temp)) { throw new Error('the value is not number!!' + temp); } result += temp; } return result; } try { document.writeln(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); //55 document.writeln(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 'u')); //the value is not number!!u } catch (e) { window.alert(e.message); }
- 再帰的な使い方
arguments.calleeを使う。
function factorial(n) { if (n != 0) { return n * arguments.callee(n - 1); } return 1; //ここを忘れがち } document.writeln(factorial(5)); //120
- 名前付き引数
名前付き引数は、関数呼び出し時に、名前を明示的に指定できる引数のこと。
1)省略可能な引数が多い
2)引数の数が多いと言う場合には有効。
function triangle(args) { if (args.base == undefined) { args.base = 1; } if (args.height == undefined) { args.height = 1; } return args.base * args.height / 2; } document.writeln(triangle({ base: 5 }, { height: 4 })); //2.5 document.writeln(triangle({ height: 2 }, { base: 4 })); //1 順序の入れ替え document.writeln(triangle({ height: 2 })); //baseを省略
関数の引数が関数になるもの。オブジェクト指向に向く。
function showElement(key, vale) { document.writeln(key + ':' + vale); } var result = 0; function addAll(key, value) { result += value; } //関数を引数にしている関数(階層が一番上) function arrayWalk(data, useFunction) { for (var key in data) { useFunction(key, data[key]); } } var ary = [1, 2, 3, 4, 5]; arrayWalk(ary, showElement); //0:1 1:2 2:3 3:4 4:5 arrayWalk(ary, addAll); //15 document.writeln(result);
- クロージャ
クロージャの概念はもやもやとして上手く理解できない・・・・。
function closure(init) { var counter = init; return function () { return ++counter; } } var myClosure = closure(1); //myClosure にclosure関数を代入。 //変数counterはスコープを超えて保持されるようになる。 document.writeln(myClosure()); //2 document.writeln(myClosure()); //3 document.writeln(myClosure()); //4
JavaScript奥深いだろ!