読者です 読者をやめる 読者になる 読者になる

Engineer as a Lifestyle @tenkoma

tenkoma's testing blog

arguments.lengthプロパティと関数オブジェクトのlengthプロパティ

2週間くらい放置していて、その間にアフィリエイトで1冊売れていました。ありがとうございます。
JavaScript 第5版 p.136 8.6.1 lengthプロパティ
JavaScriptの関数では、仮引数を指定できる。…と書いたけど、関数を定義できるプログラミング言語では普通。

function hoge(x,y,z){
    // do something.
}

ところが、JavaScriptでは関数の呼び出し時に、関数の定義時の仮引数リストの個数を超えて呼び出すことができる。

// not error.
hoge(1,2,3,"fuga");

こうして呼び出したときに、すべての引数にアクセスするには、関数の中でarguments配列を利用する。

function hoge(x,y,z){
    //console.log(arguments); // Firebug
    alert(arguments.length);
}

ところで、こんなフニャフニャ言語でも引数の数を任意の値で守らせたい場合はどうすればいいのか?
関数の処理ブロックで、簡単にチェックする方法もある。

function hoge(x,y,z){
    if (arguments.length != 3){
        throw new Error("Wrong number of arguments:" + arguments.length);
    }
    // do something.
}
hoge(1,2);// Error.
hoge(1,2,3);//not Error.
hoge(1,2,3,"fuga");//Error.

が、関数オブジェクトのlengthプロパティ(arguments.lengthとは違う)を使うとスマートに実装できる。
関数オブジェクトのlengthプロパティでは、関数定義時の引数リストの、引数の個数を調べることができる。

alert(hoge.length);// -> 3

これを利用して、呼び出し時の引数の個数が、定義時のそれと等しいかチェックする関数が、p.136で紹介されている。

function check(args){
    var actual = args.length;
    var expected = args.callee.length;//arguments.calleeで、関数オブジェクトにアクセスできる。 see p.129 8.2.2.1 calleeプロパティ
    if (actual != expected){
        throw new Error("Wrong number of arguments:" +
                        expected + "; actually passed " + actual);
    }
}
function hoge(x,y,z){
    check(arguments);
    //do something.
}

引数の個数を守らせて、間違ったときはエラーにしたいときはこのcheck(arguments);を呼び出すだけでいいらしい。