类数组
1.定义:有类似数组的属性、方法的特殊对象,最典型的是 arguments
2. arguments 特点:
function a(a,b){console.log(arguments)}
a(1,2);
可以看到控制台输出的是一个特殊的数组(数组也是对象。。),包含两个可编辑的属性 0 1 ,不可编辑的 callee( 指向函数本身 )、length...
并没有 Array.prototype 那一大堆属性和方法喔
3.自定义类数组:以 push 方法为例 ( push 底层实现是 在原有数组末尾增加元素,并改变原数组的长度,即 length 属性的值 )
var obj={
0:'a',
1:'b',
length:2,
push:Array.prototype.push
}
obj // {0: "a", 1: "b", length: 2, push: ƒ}
obj.push(3)
obj // {0: "a", 1: "b", 2: 3, length: 3, push: ƒ}
如果再增加一个数组原型对象的 splice 方法,就和 arguments 非常相似了
var obj={
0:'a',
1:'b',
length:2,
push:Array.prototype.push,
splice:Array.prototype.splice
}
obj // ["a", "b", push: ƒ, splice: ƒ]
4. push 使用后变化
var obj={
2:'a',
3:'b',
length:2,
push:Array.prototype.push
}
obj.push(1)
obj // {2: 1, 3: "b", length: 3, push: ƒ}
原理就是 push 后 length +1,然后数组下标从 0 开始计算, 最后覆盖原位置属性对应的值。
5. 扩展 push 方法
5.1 push 一个数组 : apply 方法的妙用
var arr1=[1,2],arr2=[2,3];
Array.prototype.push.apply(arr1,arr2)
arr1 // [1,2,2,3]
5.2 push 一系列数据(区分 基本参数和数组形式参数): 递归妙用
Array.prototype.mypush=function(){
var that=this;
function unitpush(arr,obj){
for(var i=0,j=arr.length;i<j;i++){
if(Object.prototype.toString.call(arr[i])==='[object Array]'){
unitpush(arr[i],that);
}else{
obj[obj.length]=arr[i];
}
}
}
unitpush(arguments,that);
return that;
}
[1].mypush(2,[3,4]) // [1, 2, 3, 4]
[1].mypush(2,[3,4],[5,[6,[7,8]]]) // [1, 2, 3, 4, 5, 6, 7, 8]