JavaScript是一门弱类型语言,它的数据类型分为两大类:简单数据类型(5种:Undefined、Null、Boolean、Number、String)和复杂数据类型(1种:Object)。Object是ECMAScript中使用最多的一个类型,所有的引用类型的值都是Object类型的实例。引用类型,本质上是一种数据结构,用于将数据和功能组织在一起。对象是某个特定引用类型的实例。
在JavaScript中,有一种特殊的对象,被称为类数组(array-like)对象,其在书中的定义为:
- 拥有length属性,其它属性(索引)为非负整数
- 不具有数组所具有的方法
类数组示例:
1:
var a = {'1':'gg','2':'love','4':'meimei',length:5};
2:
var a= {}; for(var i=0; i<10 ; i++){ a[i] = i*i; } a.length = i;
可以看出,通过将对象的每个属性名设为递增的非负整数,且动态定义一个length属性来表示元素个数,就可以使用对象来模拟数组。类数组对象可以像数组一样,使用[]通过下标访问。但它们终究只是类似数组,而不是数组,所以并不能使用数组的特有方法,如splice、indexOf、pop等。
类数组对象和数组的区别:
- 一个是对象,一个是数组
- 当新元素被添加时,数组的length属性的值会自动更新,类数组对象则不会
- 设置数组的length属性可扩展或截断数组,而对于类数组对象来说仅仅是改变了一个属性的值而已
- 类数组不能调用数组方法
类数组判断:
《javascript权威指南》上给出了代码用来判断一个对象是否属于“类数组”:
// Determine if o is an array-like object. // Strings and functions have numeric length properties, but are // excluded by the typeof test. In client-side JavaScript, DOM text // nodes have a numeric length property, and may need to be excluded // with an additional o.nodeType != 3 test. function isArrayLike(o) { if (o && // o is not null, undefined, etc. typeof o === 'object' && // o is an object isFinite(o.length) && // o.length is a finite number o.length >= 0 && // o.length is non-negative o.length===Math.floor(o.length) && // o.length is an integer o.length < 4294967296) // o.length < 2^32 return true; // Then o is array-like else return false; // Otherwise it is not }
类数组转换:
有些时候,我们需要将一个类数组对象转换为一个真正的数组,转换之后可使用数组方法
Array.prototype.slice.call(Object)
对于IE9以前的版本(DOM实现基于COM),可以使用makeArray
来实现:
// 伪数组转化成数组 var makeArray = function(obj) { if (!obj || obj.length === 0) { return []; } // 非伪类对象,直接返回最好 if (!obj.length) { return obj; } // 针对IE8以前 DOM的COM实现 try { return [].slice.call(obj); } catch (e) { var i = 0, j = obj.length, res = []; for (; i < j; i++) { res.push(obj[i]); } return res; } };
常见类数组对象:
1.arguments
//属性: length //长度 callee //正在执行的函数
arguments是最常见的类数组对象,在函数内部使用,示例:arguments[0] 或 functionName.arguments[0]
在JS的DOM中,有三个常用到的类数组对象:NodeList NamedNodeMap 和 HTMLCollection
2.NodeList
//属性: length //长度 //方法: item(idx) //通过索引访问节点
以下代码形式返回类型为NodeList:
childNodes
getElementsByClassName(className)
getElementsByTagName(tagName)
3.NamedNodeMap
//属性: length //长度 //方法: item(idx) //通过索引访问节点 getNamedItem(NS) //通过名称(和命名空间)访问节点 setNamedItem(NS) //通过名称(和命名空间)设置节点 removeNamedItem(NS) //根据名称(和命名空间)删除节点
以下代码形式返回类型为NamedNodeMap:
element.attributes
4.HTMLCollection
//属性: length //长度 //方法: item(idx) //通过索引访问节点 namedItem(name) //通过name 属性或 id 属性访问节点
以下代码形式返回类型为HTMLCollection:
document.images //所有img元素 document.links //所有带href属性的a元素和area元素 document.anchors //所有带name属性的a元素 document.forms //所有form元素 document.scripts //所有script元素 tBodies(table元素) rows(table、tbody、thead、tfoot元素) cells(tr元素)
HTMLCollection NodeList以及NamedNodeMap都是“动态的”,每当文档结构发生变化时,他们都会得到更新,始终会保存着最新,最准确的信息