伪数组
什么是伪数组?
- 定义:obj instanceof Array === false 但是有length属性
- 以下是常见伪数组:
- arguments
- NodeList、HTMLCollection
- jQuery对象
伪数组转为真·数组
- Array.prototype.splice.call(obj)
自定义伪数组
类数组
//从对象构建伪数组的两个条件://1. 具有length || 具有push\unshift\pop\shift中任意一个并调用(最终结果就是生成length这个属性)//2. 具有名为splice的方法 var obj={ length:0, splice(){}};console.log(obj);var obj2={ push:[].push, splice(){}};obj2.push();console.log(obj2);
类数组当作数组使用的原理:length相当于obj的键名
var obj={ length:0, splice(){}, push:Array.prototype.push};obj[0]=10;obj.push(1,2,3);console.log(obj);//[1,2,3,splice:f,push:f]var obj2={ length:1, splice(){}, push:Array.prototype.push};obj2[0]=10;obj2.push(1,2,3);console.log(obj2);//[10,1,2,3,splice:f,push:f]//上述push也可以用apply来写{ push:function () { return [].push.apply(this,arguments);}}
特别的,两种DOM伪数组的区别
1. getElementsByTagName 得到的是 HTMLCollections类
// 如果有一个ID为'test'的元素,可以直接取得document.getElementsByTagName('div').test
- 如上,ID元素会被直接列在HTMLCollections对象里的同名键中
- item(),length,namedItem()
2.querySelector 得到的是 NodeList类
document.querySelectorAll('div').forEach((a,b,c)=>{ console.log('第一个参数:' + a + '值'); console.log('第二个参数:' + b + '键'); console.log('第三个参数:' + c + '自身');});
- forEach()
- item(),length
- 典型ES6对象特性,entries,keys,values
共性
for(let i=0;i
- 实际上,通过控制台观察发现,两者都具备iterator接口,都可以支持for ... of语法
相比来讲,querySelector内置forEach,会更方便
援引Arguments来说事
const { callee,//函数本身 length,//参数长度 [...'所有传入的参数']//可以用下标获得所有的按顺序得到的参数}=arguments;
- 此外,arguments也具备iterator接口,可以直接用for...of遍历
总结:
- 伪数组基本上属于一个概念问题,只需要知道的是--伪数组的原型一定不是数组,所以,不会有数组的所有方法,在使用的时候不能想当然的去直接用Array.prototype方法比如push,pop,concat等等
- 伪数组转为真数组的方法有好多种,列下思路:
- 1.遍历伪数组存入真数组
- 2.Array.prototype.splice.call(obj)
- 3.Array.from()
- 4.原型继承,arr.__proto__=Array.prototype
- 5.其他工具库中的方法,如jQuery中的makeArray()toArray()等