我正在浏览MooTools的源代码,以尝试了解其.implement().extend()实用程序。

每个的定义都引用一个如下定义的函数:

var enumerables = true;
for (var i in {toString: 1}) enumerables = null;
if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];

Function.prototype.overloadSetter = function(usePlural){
    var self = this;
    return function(a, b){
        if (a == null) return this;
        if (usePlural || typeof a != 'string'){
            for (var k in a) self.call(this, k, a[k]);
            if (enumerables) for (var i = enumerables.length; i--;){
                k = enumerables[i];
                if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
            }
        } else {
            self.call(this, a, b);
        }
        return this;
    };
};

但是,我很难理解它的作用。

您能解释一下该功能的工作原理以及它的作用吗?

最佳答案

重载设置
overloadSetteroverloadGetter是两个函数修饰器方法。 overloadSetter函数用于将具有签名fn(key, value)的函数转换为可以接受对象参数的函数,即fn({key: value})

为此,overloadSetter必须包装原始函数。该包装函数具有签名fn(a, b),它是fn(key, value)的快捷方式。这实际上成为原始功能的新重载版本。

此重载函数要做的第一件事是检查所传递的key参数(a)是否为字符串类型。如果不是字符串,则该函数假定我们正在传递一个对象。因此,它将遍历对象中的每个键值对,并将原始函数应用于该对象。另一方面,如果它是字符串,则仅将函数应用于ab参数的值。

示例

为了说明这一点,假设我们具有以下功能:

var fnOrig = function(key, value){
    console.log(key + ': ' + value);
};

var fnOver = fnOrig.overloadSetter();

fnOver('fruit', 'banana');
fnOver({'fruit': 'banana', 'vegetable': 'carrot'});

在第一次调用中,使用两个参数(键和值)调用fnOver函数。当该函数检查a参数值的类型时,它将看到它是一个字符串。因此,它将仅调用原始的fnOrig函数:fnOrig.call(this, 'fruit', 'banana')。我们的控制台输出是'fruit: banana'

对于第二次调用,使用对象参数调用fnOver函数。由于我们传递了一个对象而不是字符串,因此fnOver将遍历此对象的成员,并为每个成员调用fnOrig函数。因此,在这种情况下,fnOrig将被调用两次:fnOrig.call(this, 'fruit', 'banana')fnOrig.call(this, 'vegetable', 'carrot')。我们的控制台输出是'fruit: banana''vegetable: carrot'

其他功能

在包装函数内部,您将看到对usePlural值的检查。这是overloadSetter方法本身的参数。如果将此值设置为true,则新函数会将所有参数视为对象。这意味着即使您传递了字符串键参数,它仍将作为对象处理。

另一件事是,在实际方法声明之前存在的enumerables代码,是因为它解决了某些浏览器的问题,即即使对象本身实现了自己的版本,本机Object方法也不会在for/in循环中枚举。

10-05 21:05