伪数组(ArrayLike)的总结以及应用

什么是伪数组

伪数组又称为类数组,类似数组的对象

伪数组的特征

1.按索引方式储存数据

{
	0: 'M',
	1: 'N',
	2: 'A'
}

2.伪数组是一个对象(Object),而真实的数组是一个数组(Array)。

// 用instanceof()方法进行判断
let arr = {
	0: 'M',
	1: 'N',
	2: 'A',
	length: 3,
}
let arrList = ['拉拉', '迪西', '小波', '丁丁'];
console.log(arr instanceof Array); //false
console.log(arrList instanceof Array); //true
console.log(arr instanceof Object); //true

3.具有length属性
但是length属性是静态的(真数组的长度可变),不会随着成员的变化而改变
不具有数组的push(), forEach()等方法

var arr = {
	0: 'M',
	1: 'N',
	2: 'A',
	length: 3,
}
arr.length;   //3,
arr[1];   //'b'
arr.push('d'); //Uncaught TypeError: arrLike.push is not a function
arr.length;   //3,

4.伪数组的原型链中并没有数组的原型

 arr.__proto__ === Object.prototype;   //true 
 arr instanceof Object;   //true 
 arr instanceof Array;     //false 
 // prototype 显性原型 它是函数(包括构造函数)独有的,每个函数在创建之后都有一个 prototype 属性,它是一个指针,指向函数的原型对象,这个对象包含了所有实例对象共享的属性和方法 注 通过Function.prototype.bind方法构造出来的函数是个例外,它没有prototype属性。
 // __proto__(隐式原型)是对象的一个内置属性,是JS内部使用寻找原型链的属性,也就是说,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着__proto__依次向上查找
 // 注意:用chrome和FF都可以访问到对象的__proto__属性,IE不可以。所以我们建议避免使用__proto__,因为它存在兼容性问题。
// 二者关系:一个对象的隐式原型指向构造该对象的构造函数的原型
//prototype 的作用是用来实现基于原型的继承与属性的共享。
// __proto__ 的作用构成原型链,同样用于实现基于原型的继承. 是当访问一个对象的属性时,如果内部没有该属性,就会在它的 __proto__ 属性所指的那个父对象去找,父对象没有,再去父对象的父对象里找…,直到 null,即原型链
 // 注 instanceof  用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。左值一般是一个对象,右值一般是一个构造函数 用来判断左值是否是右值的实例

5.可以通过for in和for循环遍历.

let arr = {
   0: 'M',
   1: 'N',
   2: 'A',
   length: 3,
 }
 for(var key in arr) {
   console.log(key, arr[key]) // 0 M, 1 N, 2 A, length 3
 }

常见的伪数组

1.function内arguments对象.

function test() {
  console.log(arguments, '1111111111111') // 打印结果如下图
 }
  test("name", "age");

上述代码的打印结果
2.还有像调用getElementsByTagName, document.childNodes之类的,它们都返回的NodeList对象都属于伪数组,也称为类数组.

<div class="nameList">
    <div class="name1">拉拉</div>
    <div class="name2">迪西</div>
    <div class="name3">小波</div>
    <div class="name4">丁丁</div>
  </div>
  <script>
    let nodeList = document.getElementsByTagName('div');
    console.log(nodeList)
    let childNodes = nodeList[0].childNodes;
    console.log(childNodes)
    })
  </script>

在这里插入图片描述
3.jQuery中的$()方法获取到的全部是伪数组,本质都是html标签序列.

<div class="name1">拉拉</div>
<div class="name2">迪西</div>
<div class="name3">小波</div>
<div class="name4">丁丁</div>
<script>
   $(document).ready(function() {
     let dom1 = $('div');
     console.log(dom1, '1111111111111111') // 打印结果如下图
   })
</script>

在这里插入图片描述
4.自定义的伪数组,例如 let obj={0:‘a’,1:‘b’,length:2}
5.文件域的files属性是一个伪数组

<input type="file" id="fileList">
<script>
  let fileNode = document.querySelector("#fileList")
   fileNode.addEventListener('change', function() {
     console.log(fileNode.files)
   })
</script>

上述代码console.log结果

怎么判断为伪数组

  1. instanceof() 代码同伪数组特征
  2. Array.isArray()
let arr = {
   0: 'M',
   1: 'N',
   2: 'A',
   length: 3,
}
let arrList = ['拉拉', '迪西', '小波', '丁丁'];
console.log(Array.isArray(arr), Array.isArray(arrList)); // false true

3.Array.prototype.isPrototypeOf(),用于测试一个对象是否存在于另一个对象的原型链上。

let arr = {
   0: 'M',
   1: 'N',
   2: 'A',
   length: 3,
}
let arrList = ['拉拉', '迪西', '小波', '丁丁'];
console.log(Array.prototype.isPrototypeOf(arrList)); // true
console.log(Array.prototype.isPrototypeOf(arr)); // false

4.proto.constructor,判断对象隐式原型的构造函数

let arr = {
	0: 'M',
	1: 'N',
	2: 'A',
	length: 3,
}
let arrList = ['拉拉', '迪西', '小波', '丁丁'];
console.log(arr.__proto__.constructor); //ƒ Object() { [native code] }
console.log(arrList.__proto__.constructor); //ƒ Array() { [native code] }

5.Object.prototype.toString.call()方法,传递要检查的对象作为第一个参数,

let arr = {
	0: 'M',
	1: 'N',
	2: 'A',
	length: 3,
}
let arrList = ['拉拉', '迪西', '小波', '丁丁'];
console.log(Object.prototype.toString.call(arr));  //[object Object] 
console.log(Object.prototype.toString.call(arrList)); //[object Array]

伪数组转化为真数组的方法

1声明一个空数组,遍历伪数组把它们添加到所声明的空数组中 (最原始的办法,不推荐)

let arr = {
  0: 'M',
  1: 'N',
  2: 'A',
  length: 3,
}
var arrList = []; // 声明的空数组
for (var i = 0; i < arr.length; i++) {
  arrList.push(arr[i])
}

2.使用 Array.prototype.slice.call() 或 Array.prototype.slice.apply()

let arr = {
	0: '拉拉',
	1: '迪西',
	2: '小波',
	3: '丁丁',
	length: 4,
}
var arrList1 = Array.prototype.slice.call(arr); 
console.log(arrList1); // ['拉拉', '迪西', '小波', '丁丁']
var arrList2 = Array.prototype.slice.apply(arr);  
console.log(arrList2); // ['拉拉', '迪西', '小波', '丁丁'] 

3.使用 [].slice.call(),了解一下 js 原型链可知,实际上上面第二小点中的方法和这种方法是一样的,但前者的效率相对更高。

var arrList3 = [].slice.call(arr);  
console.log(arrList3); // ['拉拉', '迪西', '小波', '丁丁']

4.使用 ES6 中的扩展运算符

var arrList4= [...arr]	// ['拉拉', '迪西', '小波', '丁丁'] 会报错,需要自己写迭代器

5.使用 ES6 中数组的新方法 Array.from()
Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

var arrList5 = Array.from(arr);
console.log(arrList5); // ['拉拉', '迪西', '小波', '丁丁']

注意这个返回的数组中,不会保留索引值以外的其他额外属性。
6.比如jQuery中$()获取的DOM伪数组,里面的context属性在被此方法转化之后就不会保留。
使用原型继承( Lis.proto = Array.prototype )

<div class="nameList">
 <div class="name1">拉拉</div>
 <div class="name2">迪西</div>
 <div class="name3">小波</div>
 <div class="name4">丁丁</div>
</div>
<script>
 var dom1 = document.querySelectorAll('div');
 console.log(dom1.constructor === Array)	// false
 dom1.__proto__ = Array.prototype
 console.log(dom1.constructor === Array)	// false
</script>
  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值