伪数组也称类数组。像arguments 或者 获取一组元素返回的集合都是伪数组。html
伪数组如何转换成真正数组,其实咱们不多去这么作,可是那帮面试官可能会问,而且不止一种方法让你去实现面试
方法1、 声明一个空数组,经过遍历伪数组把它们从新添加到新的数组中,你们都会,这不是面试官要的数组
1 var aLi = document.querySelectorAll('li'); 2 var arr = []; 3 for (var i = 0; i < aLi.length; i++) { 4 arr[arr.length] = aLi[i] 5 }
方法2、使用数组的slice()方法 它返回的是数组,使用call或者apply指向伪数组 安全
1 var arr = Array.prototype.slice.call(aLi);
模拟一下它的内部实现app
方法三 、使用原型继承spa
aLi.__proto__ = Array.prototype;
1 . 伪数组是html元素集合,虽然看着好像挺奇怪 ,可是总算转换成功,无论它。prototype
到这里我使用push() 可是居然没有变化也不报错,第一反应什么状况,方法继承却没法使用,不该该啊。试过不少方法都不行,暂时放弃了,code
后来我忽然想到我push的时候,length增长了啊,为何看不到,此次我push()更多的内容,居然出现了,length值和我push进去的length值相同,大概知道是怎么回事了,被html元素遮蔽了。具体什么缘由,或许是规范或许是安全考虑 。若是不遮蔽岂不是能修改因此html元素了 ,哈哈htm
html 元素
1 var aLi = document.querySelectorAll('li'); 2 3 console.log(aLi.constructor === Array) //false 4 5 aLi.__proto__ = Array.prototype; 6 7 console.log(aLi.constructor === Array) //true
下图证实 没有push的状况下,length = 0(实际应该是4) push()添加了9个,可是前4个被遮蔽。length=9对象
2 arguments 无影响正常使用,看来只是限制了html对象
1 function test (){ 2 arguments.__proto__ = Array.prototype; 3 arguments.push(10) 4 console.log(arguments) 5 } 6 test(1,2,3,4)
方法四、 ES6中数组的新方法 from()
1 function test(){ 2 var arg = Array.from(arguments); 3 arg.push(5); 4 console.log(arg);//1,2,3,4,5 5 6 } 7 test(1,2,3,4);
方法5 、 顺便说下jq的makeArray(),toArray()方法 它们也能够实现伪数组转数组的功能,可是实现的原理并不太同样
core_deletedIds = []
core_slice = core_deletedIds.slice,
core_push = core_deletedIds.push,
toArray: 使用了数组的slice方法
makeArray:使用了push方法
var aDiv = $('div'); console.log($.isArray(aDiv)); //false var aDiv = aDiv.toArray(); //实例方法 var aDiv = $.makeArray(aDiv);//静态方法 console.log($.isArray(aDiv));//true