function(a, i, j, res){ res = []; Ext.each(a, function(v) { res.push(v); }); return res.slice(i || 0, j || res.length); } :
下面看看这个闭包里到底有什么东西。
isIterable = function(v){ //check for array or arguments if(Ext.isArray(v) || v.callee){ return true; } //check for node list type if(/NodeList|HTMLCollection/.test(toString.call(v))){ return true; } //NodeList has an item and length property //IXMLDOMNodeList has nextNode method, needs to be checked first. return ((v.nextNode || v.item) && Ext.isNumber(v.length)); },
这个函数是判断传入的参数是否可以迭代,其实就是判断它是不是个数组和类数组。
这里涉及到一个js非常有趣的地方,就是类数组
什么是类数组?
类数组是像数组的对象。
也许就如js是鸭子类型那样,我理解的类数组,就是具有了可以像数组一样那样操作的基础,但它并不是数组或者其子类
就如上面注释那样,arguments,NodeList(node.clidenNodes返回值),HTMLCollection都是比较常见的类数组。
如下面代码(测试代码,与EXT无关)
(function test(){ f={ length:"f" }; f=Array.prototype.slice.call(f); alert(f instanceof Array);//true })();
网上很多资料都说,只要有对象有length属性,可以用下面这个小技巧将对象转换为真正的数组,call真的太灵活了
Array.prototype.slice.call(f)
但是,我实验,在标准的游览器中,length属性甚至都是不需要的,只要是对象(基本类型不行),就可以转为数组,
而在IE,没有length属性,会报错。
求人解释。
EXT也有自己转换数组的方法,这个函数比较有意思,它会立即执行,判断游览器,返回其闭包:
toArray : function(){ return isIE ? function(a, i, j, res){ res = []; Ext.each(a, function(v) { res.push(v); }); return res.slice(i || 0, j || res.length); } : function(a, i, j){ return Array.prototype.slice.call(a, i || 0, j || a.length); } }(),
值得注意的是,DOM。
IE并实现DOM的方式比较特殊,是COM模型,,所以比较遗憾,并不能用
Array.prototype.slice.call(a, i || 0, j || a.length)把NodeList转换为数组。
所以对于IE采用这种方式。
function(a, i, j, res){
res = [];
Ext.each(a, function(v) {
res.push(v);
});
return res.slice(i || 0, j || res.length);
} :