MooTools 1.4 源码分析 -overloadSetter

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;
    };
};

overloadSetter连同overloadGetter,两种功能的装饰方法。该overloadSetter功能是用来将具有签名FN(键,值),可以接受对象参数的函数功能,即:FN({键:值})。

为了做到这一点,overloadSetter必须包装的原始功能。此包装函数签名FN(A,B),这是FN快捷键(键,值)。这实际上变成了原来的功能的新的重载版本。

这个重载函数做的第一件事是检查传入的关键参数(一)是否为字符串类型与否。如果它不是一个字符串,函数假设我们传递一个对象。因此,它遍历每个键 - 值对的对象,并适用于原有的功能吧。如果它是一个字符串,在另一方面,它简单地应用于该函数的a和b参数的值。

举个例子:

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”,“香蕉”)和fnOrig.call(this,'vegetable','carrot')。我们的控制台输出“fruit:banana”和“vegetable:carrot”。

补充说明:

里面的包装功能,你会发现有一个检查usePlural的价值。这是为overloadSetter方法本身的参数。如果将此值设置为true,则新的功能将所有参数都作为对象。这意味着,即使你传递一个字符串键参数,它仍然会被处理为一个对象。

其他的东西,可枚举代码的前奏实际的方法声明,有没有因为它解决了一些浏览器,其中原生对象的方法中的for / in循环,即使对象本身实现了自己的版本,它不一一列举。

更详细链接可以查看http://stackoverflow.com/questions/4006516/what-does-mootools-function-prototype-overloadsetter-do

原文地址:https://www.cnblogs.com/haohaoday/p/3955386.html