JavaScriptで任意の関数の戻り値の真偽を逆転するような関数を生成するには以下のようになる。
arguments変数はすべての関数で特別に用意されるローカル変数で、lengthプロパティを持っているし、一見配列のように振る舞う。
例えば、渡されたすべての引数をconsoleに出力したければ、こうなる。
でも、argumentsは本物の配列ではないので、forEachメソッドを使おうとするとうまくいかない。
なので、Arrayコンストラクタを使って、配列に変換してみよう。
これだと、うまくいくように見えるけど、引数として数値型1つのみをを渡した場合にうまくいかない。
Arrayコンストラクタは数値型の引数が1つだけ渡された場合は配列の長さとして扱ってしまうためだ。
new Array(5) は [undefined, undefined, undefined, undefined, undefined]になってしまう。
おまけにforEachメソッドは要素がundefinedの場合、コールバック関数を呼び出してくれないので、なにもconsoleに出力されなくなってしまう。
これを防ぐためにはargements.lengthが1の時は特別扱いしないといけない。
function not(pred) { return function(args) { return !pred.apply(null, arguments); } } var p = not(function () { return true; }); console.log(p()); // false p = not(function (x) { return x; }); console.log(p(false)); // true
arguments変数はすべての関数で特別に用意されるローカル変数で、lengthプロパティを持っているし、一見配列のように振る舞う。
例えば、渡されたすべての引数をconsoleに出力したければ、こうなる。
function log(args) { var i; for (i = 0; i < arguments.length; i++) { console.log(arguments[i]); } } log('banana', 'orange', 'grape'); // banana // orange // grape
でも、argumentsは本物の配列ではないので、forEachメソッドを使おうとするとうまくいかない。
function log1(args) { arguments.forEach(function (x) { console.log(x); }); } log1('banana', 'orange', 'grape'); // TypeError: arguments.forEach is not a function
なので、Arrayコンストラクタを使って、配列に変換してみよう。
function log2(args) { args = Array.apply(null, arguments); args.forEach(function (x) { console.log(x); }); } log2('banana', 'orange', 'grape'); // banana // orange // grape
これだと、うまくいくように見えるけど、引数として数値型1つのみをを渡した場合にうまくいかない。
log2(5); // なにも出力されない!
Arrayコンストラクタは数値型の引数が1つだけ渡された場合は配列の長さとして扱ってしまうためだ。
new Array(5) は [undefined, undefined, undefined, undefined, undefined]になってしまう。
おまけにforEachメソッドは要素がundefinedの場合、コールバック関数を呼び出してくれないので、なにもconsoleに出力されなくなってしまう。
これを防ぐためにはargements.lengthが1の時は特別扱いしないといけない。
function log3(args) {
args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
args.forEach(function (x) { console.log(x); });
}
log3(5);
// 5
0 件のコメント:
コメントを投稿