在javascript中NodeList和Array的区别及转换方法
随着深入理解javascript 后对于一些小知识的了解慢慢加深,这里说的是关于nodelist和array的区别,相信你一定用过toarray()方法,但是这里通过js 的方法讲解nodelist 转 array的原理!
首先从字面上区分:NodeList节点的集合,array 数组。
在Web前端编程中,我们通常会通过document.getElementsByTagName的方法取出一组相同标签的dom元素。
var anchors = document.getElementsByTagName("a");
for (i = ; i < anchors.length; i++) {
var ele=anchors[i];//取某一个元素
//some code here
}
上面的代码表示获取文档中的所有链接元素,然后遍历做一些事情。
也许你会问,通过这种方法获取的这一组dom元素不就是一个数组吗?
你看,你都可以直接获取它的length属性,还可以根据索引取到对应的单独元素,
根据大牛的著名鸭子理论,它像鸭子一样行走(有length属性),像鸭子一样叫唤(根据索引取值),那么它就是一只鸭子。结论不言自明了吧?
如果,你已经对javascript稍微有过深入的了解,有length属性,可以索引取值,一定是数组吗,好像arguments也会这么一手吧,arguments是数组?虽然在实际开发的时候,我们把它当做普通数组来操作,length和for循环使用的不亦乐乎,而且并不见得会出错。
但是,它真的不是数组(Array),而是NodeList。NodeList不是数组。
其次:论证两者之间的区别
1:属性不同
NodeList为什么不是数组?
验证NodeList是不是数组,最直接的方法也许是试一下Array专有的push和pop大法:
var anchors = document.getElementsByTagName("a");
var newEle = document.createElement("a");//新建一个a元素
anchors.push(newEle);//push
var element= anchors.pop();//pop
自己测试一下,上面的代码不管是push还是pop方法,无一例外的会提示你没有push或者pop方法。
Array也不是NodeList!
这样就结束了吗?这种片面的测试反倒使楼猪无法高枕无忧心安理得了。我们完全可以像证明arguments不是数组一样,也用同样的方法证明NodeList不是数组。看下面的代码吧:
Array.prototype.testNodeList = "test nodelist"; //数组添加原型属性
function funcNodeList() {
var links = document.getElementsByTagName("a");
alert(links.testNodeList);
}
function test() {
alert(new Array().testNodeList); //test nodelist
funcNodeList(); //#ff0000? what the hell is that?
}
test(); //测试一下
通过上面的分析,我们可以肯定NodeList不是数组(Array)了。那么如何按照我们操作集合的习惯操作NodeList呢?
2、像操作Array一样操作NodeList
既然NodeList有length,可以for循环索引取值,转换成数组还不是轻而易举?哈哈,最直接的思路是这样的:
var arr = new Array();
var anchors = document.getElementsByTagName("a")
for (var i = 0; i < anchors.length; i++) {
var ele = anchors[i];
arr.push(ele); //arr就是我们要的数组
}
明扼要说明一下吧:先new一个Array,遍历NodeList,然后将每一个单独的元素push到数组变量里,最后操作数组变量,over。有没有智商受辱的感觉?
下面是在网上google到的,两行代码就可以将NodeList转换成Array来使用了:
var anchors = document.getElementsByTagName("a");
var arr = Array.prototype.slice.call(anchors); //非ie浏览器正常
但是,最最遗憾的事情发生了:上面的代码在万恶的IE下不能正常工作,IE会给你提示: 缺少 JScript 对象。
你可能会对上面的一大段分析不屑一顾,认为没有必要将NodeList转换成Array来操作。其实,我个人也认为,不管在哪种编程语言里,类型转换都是非常不明智的行为。最常见的比如c#里的装箱和拆箱,数值型数据转换,有性能问题,一不小心还会触雷。但是为什么单独要把NodeList当做Array来处理呢?
因为动态改变NodeList的时候,直接操作NodeList很可能会误闯禁区而浑然不觉。----这才是这篇文章的重点
下面举个例子:
(1)、html文档片段
<div id="divAnchor">
<a href="http://www.cnblogs.com/jeffwongishandsome/">link test</a>
</div>
(2)、javascript测试代码
var anchors = document.getElementsByTagName("a");
for (i = ; i < anchors.length; i++) {
var ele= document.createElement("a");
ele.setAttribute("href", "http://www.cnblogs.com/jeffwongishandsome/");
ele.appendChild(document.createTextNode("new link test"));
document.getElementById("divAnchor").appendChild(ele); //div附加一个新链接
}
我们的本意是在div内,已经存在的a元素后再附加一个a元素。
猜猜啥结果?
ie挂了,页面内已经生成了n多个a链接。
for循环NodeList(前提:for循环内部添加了新的元素使nodelist长度发生了变化),它的length会不断变化上升,循环循环再循环,最后成了个死循环。
var links = document.getElementsByTagName("a");
var anchors = null; //数组
try {
anchors = Array.prototype.slice.call(links);
}
catch (e) { //兼容ie
anchors = new Array();
for (var i = ; i < links.length; i++) {
anchors.push(links[i]);
}
}
for (i = ; i < anchors.length; i++) { //数组循环 安全多了
var ele = document.createElement("a");
ele.setAttribute("href", "http://www.cnblogs.com/jeffwongishandsome/");
ele.appendChild(document.createTextNode("new link test"));
document.getElementById("divAnchor").appendChild(ele); //div附加一个新链接
}
稍微简化一下程序
var anchors = document.getElementsByTagName("a");
var len = anchors.length; //定义一个变量
for (i = ; i < len; i++) { //对局部变量len进行循环
var ele = document.createElement("a");
ele.setAttribute("href", "http://www.cnblogs.com/jeffwongishandsome/");
ele.appendChild(document.createTextNode("new link test"));
document.getElementById("divAnchor").appendChild(ele); //div附加一个新链接
}
能读到这里说明您的耐心及求学的毅力很厉害,谢谢您的观看!
在javascript中NodeList和Array的区别及转换方法的更多相关文章
- JavaScript中:表达式和语句的区别
JavaScript中:表达式和语句的区别 Javascript语言精粹:表达式是由运算符构成,并运算产生结果的语法结构.程序是由语句构成,语句则是由“:(分号)”分隔的句子或命令.如果在表达式后面加 ...
- javascript中typeof与instanceof的区别
JavaScript 中 typeof 和 instanceof 常用来判断一个变量是否为空,或者是什么类型的.但它们之间还是有区别的: typeof typeof 是一个一元运算,放在一个运算数之前 ...
- javascript中基本类型和引用类型的区别分析
大多数人系统学习过的程序设计语言,在这些语言的学习过程中最早学到的几个要点之一就是值类型和引用类型的区别.下面我们来看一下在 JavaScript 中基本数据类型(Primitive Types)和引 ...
- javascript 中 typeof 和 instanceof 的区别
在 javascript 中经常会用到 typeof 和 instanceof 来判断一个对象的类型,可能 typeof 用得多些,那来看看这两个之间的区别吧. typeof : typeof 是一个 ...
- 浅谈Java和JavaScript中变量和数据类型的区别
对于一门编程语言的学习,如果第一步是安装环境,那么第二步一定是学习这门语言的基本规则,变量和数据类型则首当其冲 JavaScipt作为一个蹭Java热度而命名的语言,在很多方面和Java也有一定的相似 ...
- Javascript中setTimeout和setInterval的区别和使用
在javascript中,window对象有两个主要的定时方法,分别是setTimeout 和 setInterval,其语法基本上相同,但是完成的功能取有区别. setTimeout方法是定时程序, ...
- 探求C#.Net中ArrayList与Array的区别 【转】
ArrayList与Array的区别概述 ArrayList 是数组的复杂版本.ArrayList 类提供在大多数 Collections 类中提供但不在 Array 类中提供的一些功能.例如 ...
- 探求C#.Net中ArrayList与Array的区别
ArrayList与Array的区别概述 ArrayList 是数组的复杂版本.ArrayList 类提供在大多数 Collections 类中提供但不在 Array 类中提供的一些功能.例 ...
- JavaScript 中 Property 和 Attribute 的区别详解
property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴. property ...
随机推荐
- 华为无线ap3010dn-agn刷成胖ap
刚买的华为ap3010dn-agn 版本为 v200R007C20SPC500 默认不带命令 ap-mode-switch [Huawei]dis version Huawei Versatile ...
- hibernate3和4中 HibernateSessionFactory中不同之处 The method applySettings(Map) from the type ServiceRegistryBuilder is deprecated - The type ServiceRegistryBuilder is deprecated
hibernate3和4中 HibernateSessionFactory中不同之处 //serviceRegistry = new ServiceRegistryBuilder().applySet ...
- Paper Reading 1 - Playing Atari with Deep Reinforcement Learning
来源:NIPS 2013 作者:DeepMind 理解基础: 增强学习基本知识 深度学习 特别是卷积神经网络的基本知识 创新点:第一个将深度学习模型与增强学习结合在一起从而成功地直接从高维的输入学习控 ...
- unity, 什么时候用静态类,什么时候用单例
如果没有成员变量,或者成员变量都是常量,则用静态类. 如果有成员变量,则用单例.(以便让成员变量有初始化机会). //静态类 public class CmyFuncs{ public float m ...
- Atitit. html 使用js显示本地图片的设计方案.doc
Atitit. html 使用js显示本地图片的设计方案.doc 1. Local mode 是可以的..web模式走有的不能兰.1 2. IE8.0 显示本地图片 img.src=本地图片路径无 ...
- AAtitit.随时间变色特效 ---包厢管理系统的规划titit.随
Atitit.随时间变色特效 ---包厢管理系统的规划 1 流程滴定仪 定义的参数 颜色.位置(开始值,结束值,当前比值) >>返回数值 可以后期处理转成双位16进制码 分别定义复合颜色的 ...
- MooseFS基础和安装
一.MooseFS简介 1.介绍 MooseFS是一个具备冗余容错功能的分布式网络文件系统,它将数据分别存放在多个物理服务器单独磁盘或分区上,确保一份数据有多个备份副本.对于访问的客户端或者用户来说, ...
- 在元素的装载数量明确的时候HashMap的大小应该如何选择。
今天看到美团招聘给出了一道小题目,关于HashMap的性能问题.问题如下: java hashmap,如果确定只装载100个元素,new HashMap(?)多少是最佳的,why? 要回答这个问题,首 ...
- deepin linux 15.3安装完eclipse启动报错An error has occurred.
原因是系统中安装了jdk9 导致的. 卸载jdk9就可以了 $ java -version Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings ...
- Hive分析窗体函数之SUM,AVG,MIN和MAX
行 AVG(pnum) OVER(PARTITION BYpolno ORDER BY createtime ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOW ...