JavaScript 和柯里化(Currying)

标签 javascript closures anonymous-function currying partial-application

我正在阅读 John Resig 的《Javascript ninja secret 》,并正在尝试其中一个关于柯里化(Currying)和 parital 函数的示例。代码如下:

<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 invoking on the apply function。

我似乎无法弄清楚原因,因为这一切似乎都有道理。 bindClick 将返回一个匿名函数,该函数以 window 作为函数上下文 (this) 调用函数 elem.addEventListener参数将是 ["click", function() {console.log("OK"); }]

最佳答案

问题是您丢失了元素的上下文。必须在元素上调用 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))
         );
     }; 
};

这是一个working example 。请注意在返回的函数中添加了一个 context 参数,还要注意在 slice 调用中添加了第二个参数 - 这是删除新的 context 所必需的 参数,并且仅应用以下任何参数。

关于JavaScript 和柯里化(Currying),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15566519/

相关文章:

Javascript 运行两次而不是一次

javascript - owl-carousel 使用 Javascript 动态添加图片

javascript - 闭包名称与其中的同名函数冲突,但仅限于 Chrome

python - 关闭 __class__

matlab - 在匿名函数内联中将 NaN 设置为零

javascript - 如何在 d3.js 中制作圆形图像

javascript - jQuery Mobile - 如何强制重新创建页面 - pagebeforecreate 事件

javascript - 为什么这个闭包不能访问 'this' 关键字? -jQuery

PHP 匿名函数作为默认参数?

javascript - 为什么 Node.js 中非交互式 Function 对象内的上下文不同?