在JavaScript中解压缩“this”


这篇文章解释了在JavaScript中解currying和currying的应用程序。它是由一个tweet布兰登·艾希的。

要理解什么是uncurrening,以及它为什么有用,我们首先需要看看泛型方法。

泛型方法

通常情况下,方法与其类型紧密相关:只有当对象是方法类型的实例时,才能在对象上使用它。然而,有些方法非常有用,如果我们也能将它们应用于其他类型的实例,那就太好了。例如:
    // Simplified version of the actual implementation:
    Array.prototype.forEach = function (callback) {
        for(var i=0; i<this.length; i++) {
            if (i in this) {
                callback(this[i], i);
            }
        }
    };
这可以被认为是forEach()的隐式参数。forEach()与任何this参数一起工作,这些参数可以执行以下任务。
  • length属性:this.length
  • 属性访问:this[i]
  • 检查属性的存在:i在此
arguments对象(保存函数的实际参数)是数组的实例,因此不能直接使用forEach()。但是它可以做上面提到的所有事情。为了将forEach()应用于它,我们只需要使它成为一个显式参数(而不是隐式的)。幸运的是,函数有一个call()方法允许我们这样做:
    function printArgs() {
        Array.prototype.forEach.call(arguments, function (elem, index) {
            console.log(index+". "+elem);
        });
    }
call()比forEach()多一个参数:它的第一个参数是this的值。互动:
    > printArgs("a", "b")
    0. a
    1. b
JavaScript中有几个方法是通用的,它们大多在
Array.prototype

取消此

在一个方法中取消这一点意味着从一个签名
    obj.method(arg1, arg2)
给一个签名
    method(obj, arg1, arg2)
当一个方法被常规应用时,取消currying允许你使它变得更漂亮。示例:
    Array.forEach = Array.prototype.forEach.uncurryThis();
    function printArgs() {
        Array.forEach(arguments, function (elem, index) {
            console.log(index+". "+elem);
        });
    }
有一个proposal用于在ECMAScript的未来版本中对所有数组方法执行此操作。以下是实现uncurrythis的三种方法。

版本1:真正发生的是什么[作者:艾希,略有修改]?

    Function.prototype.uncurryThis = function () {
        var f = this;
        return function () {
            var a = arguments;
            return f.apply(a[0], [].slice.call(a, 1));
        };
    };
版本2:函数的未修改版本与在原始函数上调用call()方法相同。我们可以通过bind()借用该方法:
    Function.prototype.uncurryThis = function () {
        return this.call.bind(this);
    };
版本3:最好定义标准方法,而不太依赖外部方法。此外,在ECMAScript5之前,bind()不存在。因此,我们将第2版重写如下。
    Function.prototype.uncurryThis = function () {
        var f = this;
        return function () {
            return f.call.apply(f, arguments)
        };
    };
上面的代码仍然是“借用call()方法”的脉络。

用curring这个

uncurryThis()的逆函数称为curryThis(),每当一个方法想要将它的this传递给嵌套函数时,它就很有用。而不是写作
    var obj = {
        method: function (arg) {
            var self = this; // let nested function access `this`
            someFunction(..., function() {
                self.otherMethod(arg);
            });
        },
        otherMethod: function (arg) { ... }
    }
你会写
    var obj = {
        method: function (self, arg) { // additional argument `self`
            someFunction(..., function() {
                self.otherMethod(arg);
            });
        }.curryThis(), // introduce an additional argument
        otherMethod: function (arg) { ... }
    }
我们把隐式参数this变成了显式参数self。换句话说:我们已经从一个动态的这个变成了一个词汇上的自我。如果这始终是一个显式参数,JavaScript会更简单。

实现curryThis():

    Function.prototype.curryThis = function () {
        var f = this;
        return function () {
            var a = Array.prototype.slice(arguments);
            a.unshift(this);
            return f.apply(null, a);
        };
    };

 

发件人http://www.2ality.com/2011/11/uncurrying-this.html