js的类数组对象HTMLCollection,NodeList,arguments

2015-10-09 散崖 4817人已阅读

      说起类数组对象,早期之前就因为函数的arguments,而接触这东西,只知道类数组对象不是数组,对其深层含义并没有很好的理解。最近在看司徒正美的《js框架设计》的时候,对于argument的数组化处理,makearray函数的使用,自己也加深对于js类数组的理解!类数组:拥有length的属性,但不是数组,没有forEach、map、slice等数组方法

一、类数组的常见三个对象

       1.函数的arguments

      arguments:代表传给函数的参数的个数(没有参数的时候就是undefined)。它是个对象(不是数组),有length属性,可以通过arguments[n]来访问,如果我们要传递给函数的参数转化成熟组的时候,可以很方便运用:[].slice.call(arguments)来使arguments转换成一个数组对象,让arguments具有slice()方法!

       2.HTMLCollection对象

       HTMLCollection是一个接口,表示HTML元素的集合,提供可以遍历的列表的方法和属性。拥有length,item,nameItem属性。返回HTMLCollection集合的有:Document (images, applets, links, forms, anchors),form (elements),map (areas),select (options),table (rows, tBodies),tableSection (rows),row (cells),我们弄个例子在控制台输出就一目了然了:


       3.NodeList对象

       NodeList代表了一个有顺序的的节点列表!拥有length,item属性!返回NodeList集合的有:document.getElementsByName,document.querySelectorAll,document.getElementById("table").childNodes,document.styleSheets,同样的我们在控制台输出:


二、类数组转化成数组

        对于类数组转化成数组,上面三个类数组对象是不一样的!,其中argument比较容易,而HTMLCollection、NodeList不是则需要做一定的处理:

       1.arguments

        arguements的数组化,只需要运用[].slice.call(),方法便可以将传递给函数的参数数组化:

function Person(){
	var args=[].slice.call(arguments);
	console.dir(args);//[10,20] 参数被转化成数组
}
Person(10,20);

       2.HTMLCollection和NodeList

        对于这两个类数组对象的元素集合,如果我们使用【】.slice.call()的方式,我们发现IE8及以下的浏览器竟然会报错,报错的内容是:"Array.prototype.slice: 'this' 不是 JavaScript 对象",很明显的我们发现低版本的IE浏览器的HTMLCollection和Nodelist并是不是Object的子类。所以为了让类数组转化成纯数组,我们需要进行一定的处理,借鉴几个类库的写法,我们可以:

       ① jQuery的早期makeArray的做法:

var div=document.getElementsByTagName("div");
function makeArray(array) {
	var ret = [];
	if( array != null ){
	var i = array.length;
		// The window, strings (and functions) also have 'length'
		if( i == null || typeof array === "string" || array.setInterval )
			ret[0] = array;
		else
			while( i )
				ret[--i] = array[i];
		}

	return ret;
}
var arr=makeArray(div);
console.dir(arr) 

       ②Prototype的makeArray的做法:

//这部分主流高版本的浏览器就会使用这个函数
var makeArray = function(array, results) {
	array = Array.prototype.slice.call( array, 0 );
	if ( results ) {
		results.push.apply( results, array );
		return results;
	}

	return array;
};
//对于低版本的浏览器进行探测,IE8及以下浏览器就会使用下面重载的makeArray
try {
	Array.prototype.slice.call( document.documentElement.childNodes, 0 );

} catch(e){
	makeArray = function(array, results) {
		var ret = results || [];

		if ( toString.call(array) === "[object Array]" ) {
			Array.prototype.push.apply( ret, array );
		} else {
			if ( typeof array.length === "number" ) {
				for ( var i = 0, l = array.length; i < l; i++ ) {
					ret.push( array[i] );
				}
			} else {
				for ( var i = 0; array[i]; i++ ) {
					ret.push( array[i] );
				}
			}
		}

		return ret;
	};
}

 

交换友情链接