コメント(全5件)
1〓5件を表示
ななし ― 2005-12-14 16:18
はじめまして。ななしと名乗ります。
// JS 歴は、NN2 の終わり頃からなので、8年強です。
// ECMA262-1,2,3 はそれなりに追ってきたつもりですが、
// JavaScript-C 実装のごく一部しか読解していない程度のヘタレです。
> 引数に配列があるとそれを展開してしまうのだ。
さすがです。多くの人が手を抜いたり、そもそも、気付いていませんよね。
// Function#apply で展開された引数リストの内、
// 配列は、Array#concat で更に展開されてしまう。
// 逆に、これを利用すれば、Ruby の Array#flatten あたりは
// 簡潔に書けて真似出来ますよね。
そこで、Array#splice を使ってみました。
また、"self" が "this" を使っている場合に備えて、
"thisArg" と言う名前の引数を持てるようにしてみましたので、
function の入れ子は元に戻っています。
function Function_prototype_curry(thisArg) {
var f = this;
return function () {
var as = arguments;
Array.prototype.splice.call(as, 0, 0, 0, 0);
return function () {
Array.prototype.splice.apply(arguments, as);
return f.apply(thisArg, arguments);
};
};
}
nanto_vi ― 2005-12-15 14:05
なるほど。Arguments オブジェクトをどうやって Array にするか / Array として扱うかには悩んだのですがその手がありましたか。ありがとうございます。
ちなみに Array#flatten は前に試したことがあります。
「多元配列を一元配列に変換」
[URL]
はじめまして。nak2kと申します。
「ななしさんからのヒントにより〜」の箇所の関数なのですが、カリー化functionを生成したコンテキストにクロージングされた変数 args を Array#push で変更してしまってるために、以下のような形で意図しない動作になりませんか?
function test(a,b,c,d) { return a+b+c+d; }
var f = test.curry(1,2);
f(3,4); // --> 10, args == [1,2,3,4]
f(2,4); // --> 10, args == [1,2,3,4,2,4]
f(1,4); // --> 10, args == [1,2,3,4,2,4,1,4]
ちなみに私の場合、ArgumentsオブジェクトのArray化は、 Array.apply(null, arguments) で行うことが多いのですが、今回のケースではななしさんのArray#splice方式のほうが性能よさそうですね。(splice.call 呼び出しの引数に 0 が4つある意味が一瞬分かりにくかったですが^^;)
nanto_vi ― 2005-12-19 22:43
あー、確かにそうですね。全然気づいて (テストして) いませんでした。ご指摘ありがとうございます。早速修正しました。
# ななしさんの splice に 0 が 4 つは私も最初「?」でした。
大変勉強になりました。
ありがとうございます。
セ記事を書く