一、背景介绍
Leo 部门最近来了位前端实习生 Robin,作为徒弟,Leo 认真的为 Robin 介绍了公司业务、部门工作等状况,还有前端的新人学习地图。
接下来 Robin 开始一周欢快的学习啦~
一周后,Leo 为 Robin 同学安排了学习作业,开发一个【人员搜寻抉择】的页面,成果大抵如下:
Robin 看完这个效果图后,一脸得意的样子,这的确不难呀~
过几天后,Robin 带着本人写的代码,给 Leo 展现了她的代码,并纳闷的问到:
她将这个“数组”输入到控制台:
Leo 看了看代码:
getUserList(){ const memberList = $('#MemberList li'); memberList.map(item => { console.log(item) }); console.log(memberList);}
Leo 又问到:
Robin 一脸纳闷,而后 Leo 再原来代码上,加了个 Array.from
办法如下:
getUserList(){ const memberList = Array.from($('#MemberList li')); memberList.map(item => { console.log(item) }) console.log(memberList)}
而后从新执行代码,输入上面后果:
Leo 输入的后果,跟 Robin 说到:
Robin 满脸期待望着徒弟,对类数组对象更加充斥期待。
二、类数组对象介绍
2.1 概念介绍
所谓 类型化数组对象(简称类数组对象) 是一种相似数组的对象,它提供了一种用于拜访原始二进制数据的机制。JavaScript引擎会做一些外部优化,以便对数组的操作能够很快。然而,随着Web应用程序变得越来越弱小,尤其一些新减少的性能例如:音频视频编辑,拜访WebSockets的原始数据等,很显著有些时候如果应用JavaScript代码能够疾速不便地通过类型化数组来操作原始的二进制数据将会十分有帮忙。 —— 《MDN 类型化数组》
那么什么样的数组咱们能够归类到类型化数组中?
其实比较简单,和数组构造相似,领有 length
属性,能够通过索引来拜访或设置外面的元素,然而不能应用数组的办法,就能够归类为类型化数组。
举个例子????:
const arrLike = { 0: 'name', 1: 'age', 2: 'job', length: 3}
2.2 常见类数组对象
arguments
对象;
function f() { return arguments;}f(1,2,3)// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
NodeList
(比方document.getElementsByClassName('a')
失去的后果;
document.getElementsByTagName('img')// HTMLCollection(3) [img, img, img]
typedArray
(比方Int32Array
);
const typedArray = new Uint8Array([1, 2, 3, 4])// Uint8Array(4) [1, 2, 3, 4]
另外应用 jQuery 获取元素,会被 jQuery 做非凡解决成为 init 类型:
$('img')// init(3) [img, img, img, prevObject: init(1), context: document, selector: "img"]
当然还有一些不常见的类数组对象,比方“Storage API 返回的后果”,这里就不一一列出。
三、类数组对象属性
上面通过 Robin 代码作为示例,介绍类数组对象的属性:
const memberList = $('#MemberList li');
3.1 读写
// 读取memberList[0];// Node: <li>...</li>// 写入memberList[0] = document.createElement("div")memberList[0];// Node: <div>...</div>
3.2 长度
memberList.length; // 10
3.3 遍历
for (let i = 0;i < memberList.length; i++){ console.log(memberList[i]);}/* Node: <li>...</li> Node: <li>...</li> ... 共10个,省略其余*/memberList.map(item => console.log(item));/* 0 ... 共10个,省略其余*/
但如果是 HTMLCollection
就不能应用 map
咯:
const img = document.getElementsByTagName("img");img.map(item => console.log(item));// Uncaught TypeError: img.map is not a function
四、类数组对象解决
Leo 看了看 Robin 解决这个列表的代码:
getUserList(){ const memberList = $('#MemberList li'); const result = { text: [], dom : [], }; memberList.map(item => { item = memberList[item] // 判断以后节点是否有 checked 类名 }) console.log(result) this.showToast(`选中成员:${result.text}`);}
很显著,Robin 并没有对 jQuery 获取到的 memberList
做解决,间接应用,通过索引来获取对应值。
Leo 持续和 Robin 介绍到:
4.1 Array.from
应用 Array.from
来将类数组对象转为数组对象,操作起来非常简单:
getUserList(){ const memberList = Array.from($('#MemberList li')); // 省略其余代码}
其语法如下:
Array.from(arrayLike[, mapFn[, thisArg]])
参数:
arrayLike
想要转换成数组的伪数组对象或可迭代对象。mapFn
可选如果指定了该参数,新数组中的每个元素会执行该回调函数。thisArg
可选可选参数,执行回调函数mapFn
时this
对象。
返回值:
一个新的数组实例。
更多 Array.from
介绍能够查看文档。
4.2 Array.prototype.slice.call()
slice()
办法返回一个新的数组对象,这一对象是一个由 begin
和 end
决定的原数组的浅拷贝(包含 begin
,不包含end
)。原始数组不会被扭转。
实现代码:
getUserList(){ const memberList = Array.prototype.slice.call($('#MemberList li')); // 省略其余代码}
更多 Array.prototype.slice 介绍能够查看文档。
4.3 ES6开展运算符
开展语法(Spread syntax), 能够在函数调用/数组结构时, 将数组表达式或者string在语法层面开展;还能够在结构字面量对象时, 将对象表达式按key-value
的形式开展。
实现代码:
getUserList(){ const memberList = [...document.getElementsByTagName("li")]; // 省略其余代码}
更多 ES6开展运算符 介绍能够查看文档。
4.4 利用concat+apply
getUserList(){ const memberList = Array.prototype.concat.apply([], $('#MemberList li')); // 省略其余代码}
五、案例小结
Leo 介绍完这些常识后,Robin 又优化了下本人的代码,波及到类数组对象操作的外围 js 代码如下:
class SelectMember { constructor(){ this.MockUsers = window.MockUsers; this.init(); } init(){ this.initMemberList('#MemberList', this.MockUsers); this.initBindEvent(); } // ... 省略局部代码,保留外围代码 submitSelect(){ const memberList = Array.from($('#MemberList li')); const result = { text: [], dom : [], }; memberList.map(item => { const hasClass = $(item).children('.round-checkbox').children('span').hasClass(this.selectClassName); if(hasClass){ result.text.push($(item).children('.user-data').children('h4').text()); result.dom.push(item); } }) this.showToast(`选中成员:${result.text}`); }}let newMember = new SelectMember();
很显著,应用正确形式来解决类数组对象,不仅能使咱们代码更加少,缩小转换解决,还能进步代码品质。
整个我的项目的残缺代码,能够在我的 github 查看:
https://github.com/pingan8787/Leo-JavaScript/blob/master/Cute-Demo/10.Learn-Array-Liked-Objects/index.html
六、总结
本文咱们通过一个理论场景,具体介绍了类数组对象在理论开发中的应用,对于常见的类数组对象,咱们还介绍了解决形式,能很大水平缩小咱们解决类数组对象的操作,将类数组对立转成数组,更加不便对数据的操作。
心愿看完本文的你,当前再遇到类数组对象,不会再一脸懵逼咯~~~