数组与类数组以及在类数组对象使用数组的方法

如何在类数组中使用数组的方法?
这里记点笔记,仅供学习参考。



判定数组

1. Array.isArray( )

给定一个未知的对象,判断它是否为数组?
我们通常用数组的一些特性来进行判断。在ES5中,可以使用 Array.isArray()函数来做这件事:

	Array.isArray([]);		// true
	Array.isArray({});		// false

在这里插入图片描述


但是在ES5之前,typeof在这里却没什么用。对于数组,它的返回值为一个对象(对于除了函数以外的所有值都是如此)。
在这里插入图片描述


2. instanceof 操作符

instanceof操作符也只能用语简单的情形:

	[] instanceof Array		// true
	({}) instanceof Array 	// false

在这里插入图片描述
但使用 instanceof 的问题在于,web浏览器可能会有多个窗口存在,每个窗口都偶有自己的一个JavaScript环境,有自己的全局对象。并且,每个全局对象都有自己的一组构造函数。因此一个窗口中的对象将不可能是另外窗体中的构造函数实例。窗体之间的混淆不常发生,但这个问题足以证明 instaceof操作符不能视为一个可靠的数组检测方法。


3. 检测类属性

对于数组而言,数组的属性总是“Array”,因此在ES3中的isArray()函数的代码可以这样写:

var isArray = Array.isArray || function(o) {
	return typeof o === "object" &&
	Object.prototype.toString.call(o) === "[object Array]";
}

实际上,这里的类属性检测就是ES5中 Array.isArray() 函数所做的事情。


数组

在JavaScript中,数组有一些特性是其他对象所没有的:

  • 当有新元素添加到列表中时,自动更新 length 属性。
  • 设置 length 为一个较小的值将截断数组。
  • 从 Array.prototype 中继承一些有用的方法。
  • 其类属性为 “Array”。

这些特性让 JavaScript 数组和常见的对象有明显的区别。但是它们不是定义数组的本质特性。一种常常完全合理的看法把拥有一个数组为 length 属性和对应非负整数属性的对象看做一种类型的数组。


类数组

这些拥有length属性、并且非负整数属性的对象可以看做是“类数组”。
对于真正数组的遍历,很多数组算法针对类数组对象工作,也可以像针对真正的数组一样。

以下代码是为一个常规对象增加了一些属性使其变为类数组对象,然后遍历生成的伪数组的“元素”:

	var a = {};		// 从一个空对象开始
	var i= 0;		// 添加一些属性,使其成为“类数组”
	while(i < 10) {
		a[i] = i * i;
		i++;
	}
	a.length = i;

现在,把它当做真正的数组去遍历它:

	var total = 0;
	for(var j = 0; j < a.length; J++) {
		total += a[j];
	}

在客户端 JavaScript 中,一些 DOM 方法(如,document.getElementByTagName() )也返回类数组对象。下面的函数可以用来检测类数组对象

  1. 判定o是否是一个类数组对象
  2. 字符串和函数都有length 属性,但是它们可以用 typeof 检测将其排除。
  3. 在客户端 JavaScript 中,DOM 文本结点也可以有 length 属性,需要用额外的 nodeType != 3 将其排除
	function isArrayLike(o) {
		if (o&&										// o 非 null 、undefined 
			typeof o === "object" &&				// o 是对象
			o.length >= o &&						// o.length 是有限数值
			o.length === Math.floor(o.length) &&	// o.length 是整数
			o.length < 4294967296 )					// o.lengrh < 2^32
			return true;		// o 是类数组
		else
			return false;		// o 不是
	}

类数组对象使用数组方法

JavaScript 数组的方法是特意定义为通用的,因此它们不仅应用在真正的数组上,而且,在类数组上也可以使用。

  • 在ES5中,所有数组的方法都是通用的。
  • 在ES3中,除了toString()toLocaleString()以外的所有方法也是通用的。
  • 类数组对象没有继承自Array.prototype,那就不能在它们上面直接调用数组的方法。尽管如此,也可以间接的使用Function.call方法调用:
	var a = {"0": "a", "1": "b", "2": "c", length: 3};		// 类数组对象
	Array.prototype.join.call(a, "+");						// => "a+b+c"
	Array.prototype.slice.call(a, 0);						// => ["a", "b", "c"] 真正的数组
	Array.prototype.map.call(a, function(x) {
		return x.toUpperCase();								// => ["A", "B", "C"]
	})

ES5 数组的方法是在 Firefox 1.5 中引入的,同时 Firefox 将这些方法在 Array 的构造函数上直接定义为数组。即可以写为:

	var a = {"0": "a", "1": "b", "2": "c", length: 3};		// 类数组对象
	Array.join(a, "+");						// => "a+b+c"
	Array.slice(a, 0);						// => ["a", "b", "c"] 真正的数组
	Array.map(a, function(x) {
		return x.toUpperCase();				// => ["A", "B", "C"]
	})

总结

当用在类数组对象上时,数组的方法的静态函数版本非常有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值