2

私は John Resig の Secrets of Javascript ninja を読んでいて、カリー化と部分関数の例の 1 つを試していました。コードは次のとおりです。

<html>
<body>
<button id="test">Click Me!</button>
</body>


<script type="text/javascript">
    Function.prototype.curry = function() {
        var fn = this,
        args = Array.prototype.slice.call(arguments);

       return function() {
           return fn.apply(this, args.concat(
               Array.prototype.slice.call(arguments)));
           }; 
       };


    var elem = document.getElementById("test"); 
    var bindClick = elem.addEventListener.curry("click");
    bindClick(function(){   console.log("OK"); });
</script>
</html>

ただし、次のコードは Uncaught TypeError: Illegal invocation on the apply function というエラーを生成するようです。

それはすべて理にかなっているように見えるので、理由を理解できないようです。 関数コンテキスト ( ) として関数をbindClick呼び出す無名関数を返し、引数は次のようになります。elem.addEventListenerwindowthis["click", function() {console.log("OK"); }]

4

1 に答える 1

3

問題は、要素のコンテキストを失ったことです。メソッドはaddEventListener要素で呼び出す必要がありますが、関数で呼び出しています。

// Here, `this` refers to a function, not an element
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));

要素を新しい関数に渡す必要があります。例えば:

Function.prototype.curry = function () {
    var fn = this,
    args = Array.prototype.slice.call(arguments);

     return function (context) {
         return fn.apply(
             context,
             args.concat(Array.prototype.slice.call(arguments, 1))
         );
     }; 
};

これが実際のです。返された関数に引数が追加されていることに注意してください。また、呼び出しcontextに 2 番目の引数が追加されていることにも注意してください。これは、新しい引数を削除し、後続の引数のみを適用するために必要です。slicecontext

于 2013-03-22T09:20:08.067 に答える