在javascript中NodeList和Array的区别及转换方法
随着深入理解javascript 后对于一些小知识的了解慢慢加深,这里说的是关于nodelist和array的区别,相信你一定用过toarray()方法,但是这里通过js 的方法讲解nodelist 转 array的原理!
首先从字面上区分:NodeList节点的集合,array 数组。
在Web前端编程中,我们通常会通过document.getElementsByTagName的方法取出一组相同标签的dom元素。
var anchors = document.getElementsByTagName("a"); for (i = 0; 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 = 0; 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 = 0; i < links.length; i++) { anchors.push(links[i]); } } for (i = 0; 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 = 0; 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附加一个新链接 }
能读到这里说明您的耐心及求学的毅力很厉害,谢谢您的观看!
转载于:https://www.cnblogs.com/zhaokunbokeyuan256/p/7449238.html
在javascript中NodeList和Array的区别及转换方法相关推荐
- 论numpy中matrix 和 array的区别
论numpy中matrix 和 array的区别 原文:http://blog.csdn.net/vincentlipan/article/details/20717163 数组转换矩阵: A = ...
- javascript中children和childNodes的区别
javascript中children和childNodes的区别 1.childNodes:它是标准属性,它返回指定元素的子元素集合,包括HTML节点,所有属性,文本节点. 可以通过nodeType ...
- javascript中call和apply的区别
我理解javascript中call和apply的区别仅在于语法不同. 下例中分别调用call和apply对myObj进行修改,语法不同,但使用效果是一样的: var myObj = { " ...
- JavaScript 中 Property 和 Attribute 的区别
转自:http://www.cnblogs.com/elcarim5efil/p/4698980.html property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(pro ...
- JavaScript中eval()和$.parseJSON()的区别和联系以及JSON.stringify()的区别
JavaScript中eval()和$.parseJSON()的区别和联系以及JSON.stringify()的区别 一.第一个区别是:安全性 json格式非常受欢迎,而解析json的方式通常用JSO ...
- javascript中call和apply的区别和用法
javascript中call和apply的区别和用法 1.call和apply是什么 更改对象的内部指针指向,即改变对象的this指向的内容 function Fn(){this.name='小明' ...
- javascript中基本类型和引用类型的区别分析
大多数人系统学习过的程序设计语言,在这些语言的学习过程中最早学到的几个要点之一就是值类型和引用类型的区别.下面我们来看一下在 JavaScript 中基本数据类型(Primitive Types)和引 ...
- JavaScript中的nodeName nodeType nodeValue区别
在JavaScript中,存在有nodeName .nodeType. nodeValue这三个属性,今天我们来了解下JavaScript中的nodeName .nodeType .nodeValue ...
- javascript中实例方法与类方法的区别
在javascript中,类有静态属性和实例属性之分,也有静态方法和实例方法之分 类属性(静态属性):通过类直接访问,不需要声明类的实例来访问 类方法(静态方法):通过类直接访问,不需要声明类的实例来 ...
- jQuery中的read 和JavaScript中 的onload函数的区别
2019独角兽企业重金招聘Python工程师标准>>> 在JavaScript中,onload函数是最经常用到的,这个函数的作用是等待网页完全加载之后再去执行代码块中的语句,因为按照 ...
最新文章
- C++ 笔记(18)— 类和对象(this 指针、指向类的指针、类静态成员变量和函数)
- 基于HTML5的电信网管3D机房监控应用
- 十步,教你把Python运行速度提升 30%
- 深度学习中7种最优化算法的可视化与理解
- 如何理解 RESTful 的幂等性
- 电脑上怎么做pdf文件_PDF文件怎么加水印?PDF水印添加方法
- HTTP Error 503. The service is unavailable.
- 如何让控件span的id调用ajax_微服务架构之「 调用链监控 」
- 华为鸿蒙适配计划,华为鸿蒙适配计划提前曝光,快看看有你的机型吗?
- JQuery实现页面跳转
- java返回特定下标元素_java基础--输出数组中指定元素的下标
- 抽象同步器AQS、CAS应用之--ReentrantLock,lock和unlock的流程、源码分析
- CSS之实现二级菜单动态出现
- 同一个电脑安装几个MATLAB,同一个版本的matlab、同一个.m文件,为何一个顺利执行、另一个出错?...
- linux live运行 光盘弹出复,通过liveCD进行ubuntu启动修复
- 【计量经济学导论】16. 面板数据模型
- 宝塔面板FTP存储空间无法连接的问题
- linux编辑框软键盘自动弹出,带输入框的Dialog自动弹出软键盘
- 零基础入门学习Python视频(全42集)
- excel同一行中如何添加换行