1>$type函数
实现如下:function $type(obj){ if (obj == undefined) return false; if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name; if (obj.nodeName){ switch (obj.nodeType){ case 1: return 'element'; case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; } } else if (typeof obj.length == 'number'){ if (obj.callee) return 'arguments'; else if (obj.item) return 'collection'; /*this is defined by mootools*/ } return typeof obj;}; 如果只看第13行代码,它的实现只是简单的使用typeof操作符返回obj的类型,前面的代码只是针对几种特殊的类型作处理。如果obj是undefined返回false;如果obj有属性$family,则检查$family的属性name是否是数字,如果不是就返回name属性,反之,则返回false;如果有nodeName属性,说明它是一个DOM元素,则检查它的nodeType属性,如果是1,则返回element;如果是3,旭检查它的空白结点,还是文本结点;如果obj有length属性,则继续判断它如果有callee属性,则是一个Argument对象,返回argement;如果有item属性,则返回collection,我非常怀疑该类型是Mootools自己增加的。
2> $A与$splat
$A函数是将一个可遍历对象,转成一个数组。可遍历对象如函数参数,DOM节点集合。实现如下:function $A(iterable){ if (iterable.item){ var array = []; for (var i = 0, l = iterable.length; i < l; i++) array[i] = iterable[i]; return array; } return Array.prototype.slice.call(iterable);}; 如果iterable具有属性item,则在一个循环中把它的每一个对象都拷贝到array,否则,就用Array对象的slice函数,把这个集合一个个的“切”成数组。这里,要说明的是并不是每个浏览器都支持slice函数。该函数在String对象中常见,甚至可以猜测,这是Mootools对的Array对象的增强。 $splat则是将一个东西转成数组,而不论它本身是否是一个可遍历的集合,实现如下:
function $splat(obj){ var type = $type(obj); return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];}; 首选,获得obj的类型,首先判断type是否存在,如果不存在,则返回一个空数组;如果存在,则判断它是array,还是arguments,如果不是array且不是arguments,则将它整个变成数组,反之则返回本身。 第3条语句,用if else代码写如下:
if( type ) { if( type != 'array' && type != 'arguments' ) { return obj; }else { return [obj]; } }else{ return [];}
3> $lambda与$arguments
这两个函数放在一起,是因为它们都直接体现Javascript语言的函数编程特性,它们的返回值就是函数。实现如下:function $lambda(value){ return (typeof value == 'function') ? value : function(){ return value; };};function $arguments(i){ return function(){ return arguments[i]; };}; $lambda将会返回一个函数,这个函数的返回值就是value,如$lambda(false)。$arguments,则将返回一个函数,它将给出第i个参数的值。
var fourth = $arguments(3);alert(fourth(12, 34, 51, 45, 79));
没有评论:
发表评论