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