浅谈JavaScript和DOM中的类数组对象

时间:2022-03-02 16:12:21

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等。

类数组对象和数组的区别:

  1. 一个是对象,一个是数组
  2. 当新元素被添加时,数组的length属性的值会自动更新,类数组对象则不会
  3. 设置数组的length属性可扩展或截断数组,而对于类数组对象来说仅仅是改变了一个属性的值而已
  4. 类数组不能调用数组方法

类数组判断:

《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都是“动态的”,每当文档结构发生变化时,他们都会得到更新,始终会保存着最新,最准确的信息