伪数组

伪数组与数组的区别

通常我们从HTML的 document 中获取的节点 通常就是 伪数组
伪数组 和 数组的结构非常类似,如何分辨数组与伪数组

  1. xxx instanceof Array

这方法会 返回一个 boolean 值

  1. let divs = document.querySelectorAll('.xx')
  2. let divs2 = document.getElementsByTagName('div')
  3. let divs3 = document.getElementsByClassName('.ss')
  4. console.log(divs, divs2, divs3);
  5. console.log('伪数组是否是数组',(divs instanceof Array))

image.png

伪数组和数组之间的区别主要是 在于伪数组无法使用 数组的 方法,例如 push() , indexOf() 之类的方法

  1. divs.push(123);
  2. divs.indexOf(1);

image.png

image.png

伪数组的功能

伪数组虽然使用不了 数组原有的 api 方法,但是伪数组可以使用 索引

  1. let arrayLike = {
  2. 0: 'es6',
  3. 1: 'es7',
  4. 2: 'es8',
  5. length: 3
  6. }
  7. console.log(arrayLike[0]) // es6

伪数组转化成数组

虽然 伪数组无法调用 数组的api,但是我们可以将 伪数组转化成 数组,这样我们就可以正常使用数组的方法

ES5 方法:Array.prototype.slice.call()

let arr = Array.prototype.slice.call(divs)
console.log('arr是否是数组', (arr instanceof Array));
arr.push('111');
console.log('arr', arr);

image.png

ES6 方法:Array.from()

let arrayLike = {
  0: 'es6',
  1: 'es7',
  2: 'es8',
  length: 3
}

let arr = Array.from(arrayLike);
console.log('arr 是否是数组', (arr instanceof Array));
arr.push('123');
console.log('arr数组', arr);

image.png

其他常见的 伪数组

function foo() {
  console.log('foo() 的 arguments',arguments);
  console.log('arguments 是否为 数组', (arguments instanceof Array))
}

foo(1, 'imooc', true);

image.png

数组的扩展

new Array()

new Array() 括号内,如果传入的是一个数字,那么就会生成对应长度的空数组
如果传入的是一个,字符串,那就会自动生成一个数组
如果传入多个数字,用逗号隔开,那么也会生成一个数组

let arr1 = new Array(3)
console.log('arr1', arr1)

image.png

let arr2 = new Array(1,2,3)
console.log('arr2', arr2)

image.png

let arr3 = new Array('3')
console.log('arr3', arr3)

image.png

Array.of() 创建数组的初始值

let arr = new Array.of(1,2,3)
console.log('arr', arr)

image.png

let arr1 = Array.of(3)
console.log('arr1', arr1)

image.png
可以将一堆数据拼装成数组

copyWithin() 替换

用来替换数组中的某些元素,会改变原数组中的值
可以传入三个参数,
第一个参数:数组内被替换的目标元素的下标值
第二个参数:用来替换目标元素的,数组元素的开始下标
第三个参数:如果不传,则默认到数组的最后一位,传的话,则是数组内元素的结束下标
第二个参数和第三个参数,遵从含头不含尾的原则

第二个参数到第三个参数的长度,决定了,第一个参数开始后会被覆盖的长度

const arr1 = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
const arr2 = [1, 2, 3, 4, 5, 1, 1, 1];
arr1.copyWithin(1,2,3)
arr2.copyWithin(2,5)
console.log('arrWith1', arrWith1)
console.log('arrWith2', arrWith2)

image.png
arr1.copyWithin(1,2,3)则是,置换数组中第二个元素,置换长度为1, 根据含头不含尾的原则,用来替换的数据是数组中的第三个元素,也就是 3

arr1.copyWithin(2, 5)
从数组的第三个元素开始替换,替换元素的开始下标为数组中第六个,一直到数组的最后一位,也就是 1,1,1,因为用来替换的数组的长度是3,所以决定了他替换目标元素的长度也是3

fill() 填充

初始值的填充, new Array(数组长度).fill(填入数组的数值)

const arr = new Array(3).fill(7)
console.log('arr', arr)

image.png

fill()方法的完整的参数
fill(‘填充数据’, ‘填充的开始位置’, ‘填充的结束位置’), 会用填充数据,替换从开始位置到结束位置前的元素。
image.png

const arr = [1, 2, 3, 1, 2, 3];
console.log('arr填充前的数据', arr)
arr.fill("imooc", 1, 4);
console.log('arr填充后的数据', arr)

image.png

如果只传入一个数字,fill(‘填充的数据’), 默认用填充的数据,替换数组中的所有数据

const arr = [1, 2, 3, 1, 2, 3];
arr.fill(1)
console.log('arr填充后的数据', arr)

image.png

indexOf VS includes

  1. includes()indexOf()都是使用严格模式的判断,等同于===

    const data = ['es6', 'es9', 2]
    console.log('data', data.includes('2'))  // false
    console.log('data', data.indexOf('2') > -1)  // false
    
  2. 对于 **NaN**的 识别

indexOf() 无法判断 NAN是否存在,因为 NAN 与 NAN 并不相等

const arr = [1,2,3, NaN]
console.log('是否可以识别NaN:', arr.indexOf(NaN))
console.log('NaN是否可以相等:', NaN == NaN)

image.png
includes() 可以用来判断 NaN

const arr = [1,2,3, NaN]
console.log('includes是否可以识别NaN:', arr.includes(NaN))

image.png

  1. includes()indexOf() 都只能用来判断,数组中基本类型数据,对于对象或数组引用类型数据的判断就不生效了
    const objArr = ['es6', ['es7', 'es8'], 'es9']
    console.log('objArr', objArr.includes(['es7', 'es8'])) // false
    console.log('objArr', objArr.indexOf(['es7', 'es8']) > -1) // false
    

indexOf() ->下标

如果存在则返回 该元素在数组中的下标值,不存在返回-1

const arr = [1,2,3]
console.log(arr.indexOf(2)) // 1
console.log(arr.indexOf(4)) // -1

includes()->boolean

image.png
第一个参数是匹配项,第二个参数是数组被查找项的开始下标

const arr = ['es6', 'es7', 'es8']

console.log('arr.includes', arr.includes('es6')) // true
console.log('arr.includes', arr.includes('es9')) // false

console.log('arr.includes', arr.includes('es7', 1)) // true
console.log('arr.includes', arr.includes('es7', 2)) // false

同样第二个参数还能用负数,表示从倒数第几个元素开始往后查找,并不是下标

const arr = ['es6', 'es7', 'es8']
console.log('arr.includes', arr.includes('es7', -1)) // false
console.log('arr.includes', arr.includes('es7', -2)) // true

Array.prototype.flat() & flatMap()

flat 是平的意思,主要用来 对多维数组进行扁平化操作
flat(Number) 支持传入数字类型的参数,表示扁平化的深度

const arr = [1, 2, 3, 4, 5, [6, 7, 8, [9, 10, 11, [12, 13, 14]]]]
console.log(arr.flat())
console.log(arr.flat().flat())
console.log(arr.flat(3))

image.png

flatMap() 相当于是 map() & flat() 方法的结合体,既能遍历数组又能扁平化操作
使用map() 方法时,返回一个二维数组,然后通过 flat() 进行扁平化处理,变成一维数组

const arr = [1, 2, 3, 4, 5, 6]
const res1 = arr.map(x => [x + 1])
const res2 = arr.map(x => [x + 1]).flat()
const res3 = arr.flatMap(x => [x + 1])

console.log('map', res1)
console.log('map.flat', res2)
console.log('flatMap', res3)

image.png