JavaScriptこそ最も大衆に開かれた言語である。ブラウザあれば誰でも実行・開発できる。このサイトに基本をまとめた記事がないので少しずつまとめることにする。
■関数の定義
function文
function func(){ alert('hello'); };
JavaScriptでは以下のように関数内で関数を定義することができる。
function func(){ function getStr(){ return 'hello'; } alert(getStr()); };
但しfunction文を使用する場合は、関数の先頭で宣言したことになる。従って以下のように記述しても文法上は問題がない。
function func(){ alert(getStr()); function getStr(){ return 'hello'; } };
またfunction文を使用する場合は、if文の中などで定義できない。定義した場合はブラウザ毎に挙動が異なってしまう。
関数リテラル
var func = function(){ alert('hello'); };
function文と関数リテラルの比較
hoge();// hoge function hoge(){ alert('hoge'); } hoge();// hoge
以下のように記述するとエラーとなる。
fuga();// undefined var fuga = function(){ alert('fuga'); } fuga();// fuga
以上のようにfunction文で定義した関数は、自身のスコープの先頭で宣言したものとみなされる。一方で、関数リテラルを使用した場合は通常の変数と同じような扱いになる。
Functionコンストラクタ
関数はFunctionコンストラクタを使用して定義することもできる。
var hoge = new Function("a", "b", "return a + b;");
上述は以下の内容と同義である。
var hoge = function(){ return a + b; }
但し、Functionコンストラクタは常にトップレベルの関数としてコンパイルされる。非常にコードが読みにくく使用されることはあまりない。
■引数
以下のように、定義より少ない引数の数で呼び出すことができる。
var func = function(a, b){ b = (!b)? 'です' : b; alert(a + b); }; func('これはペン');//これはペンです func('これはペン', 'だ');//これはペンだ
JavaScriptでは引数の型やデフォルト値などを指定することはできないので、必要に応じて関数内でそのロジックを実装せねばならない。
argumentsオブジェクト
引数の長さが可変の場合は、以下のようにargumentsオブジェクトを使用するのも良い。
var max = function(){ var n = Number.NEGATIVE_INFINITY; for(var i = 0, n = arguments.length; i < n; i++){ if(arguments[i] > n){ n = arguments[i]; } } return n; }; alert(max(1, -100, 10, 150, 2457));
また、以下のようにargumentsオブジェクトのcalleeプロパティには、現在実行中の関数の参照が格納されている。
alert((function(n){ if(n > 1){ return n * arguments.callee(n - 1); } else{ return 1; } })(5));//120
匿名関数において自身が呼び出せるので再帰などに有用である。
argumentsオブジェクトの特性
- 配列の特性を持っているが厳密にはオブジェクトである
- lengthプロパティを変更しても要素数には変化が及ばない
- 引数の参照が渡されているため、代入により引数自体を変更できる
- 同名の引数があった場合は上書きされてしまう
引数と可読性について
引数の数が増えてくると可読性が下がる。
var hoge = function(name, age, gender, origin, lang){ // something }
以下のようにオブジェクトリテラルを使用して記述するのもよい。
var hoge = function(arg){ var name = arg['name']; var age = arg['age']; var gender = arg['gender']; var origin = arg['origin']; var lang = arg['lang']; }