hzzzzzzzq / Blog

这是我记录博客的地方,希望能多写一些技术博客,JS、ES、React、Vue等
14 stars 0 forks source link

ES 6 系列 - 6. 数组扩展 #7

Open hzzzzzzzq opened 2 years ago

hzzzzzzzq commented 2 years ago

数组的扩展

扩展运算符

基本使用,扩展运算符是什么,其实就是三个点( ... ),在2. 变量的解构赋值 - 数组4. 函数的扩展 - rest参数中,接触过。

其实就是讲一个数组转为用逗号分隔的参数序列。

let arr = [1, 2, 3, 4, 5];
console.log(...arr); // 1 2 3 4 5

let str = 'Hello';
console.log(...str); // H e l l o

从上面的代码中,我们能够看出,其实扩展运算符就是拆解数组、字符串等类似结构。

当然,在这里需要注意的是只能拆一层的内容,如果数组中有对象,或者嵌套了一个数组是不可拆的

let arr = [1, 2, {a: 1}, 4];
console.log(...arr); // 1 2 { a: 1 } 4

对象中使用大多用来拷贝一个对象,并进行部分修改

let obj = {
  a: 1,
  b: 2,
  c: {
    x: 3,
  },
};
// 下面的 a: 4,就是对a的值进行修改。
let obj2 = {...obj, a: 4};
console.log(obj2);
// a: 4
// b: 2
// c: { x: 3 }

数组新增的方法

Array.form()

该方法用于将类似数组的对象可遍历的对象转为真正的数组

let arrayLike = {
  '0': 'x',
  '1': 'y',
  '2': 'z',
  length: 3
}
let arr = Array.from(arrayLike);
console.log(arr); // ['x', 'y', 'z']

Array.of()

该方法用于将一组值转化成数组

let arr = Array.of(1, 2, 3, 4);
console.log(arr); // [1, 2, 3, 4]

新增的实例方法

find() 和 findIndex()

find() 方法,简单来说就是在数组中找出想要的那个值

可以传入三个参数,第一个参数表示,当前值;第二个参数表示,当前值所在数组中的位置;第三个参数表示,原数组。当然,find() 顾名思义,就是查询,会找出第一个返回 true 的成员。

let arr = [1, 3, 5, 7, 9];
const value = arr.find(val => {
  return val > 7
});
console.log(value); // 9

// 来看看有两个相同值时,返回的是哪个值?
const value2 = arr.find(val => {
  return val > 6
});
console.log(value2); // 7

find() 方法中,可以传递第二个参数,用来绑定 this

let age = {
  first: 10,
  second: 20,
};
let ages = [11, 20, 22];
const value = ages.find(function (val) {
  return val > this.first
}, age);
console.log(value); // 11

在上面通过参数二传入一个对象,来绑定 this。当然这里可以会有疑问,为什么不用箭头函数了? 这里具体可以去看看 [普通函数与箭头函数的 this 指向问题]()。

findIndex() 方法与 find() 方法非常接近,返回第一个符合条件的成员的位置(也就是数组的下标),如果找不到,则返回 -1

let arr = [1, 3, 5, 7, 9];
const index = arr.findIndex(value => {
  return value > 7;
});
console.log(index); // 4

// 来看看两个符合条件值时,返回是第几个的位置?
const index2 = arr.findIndex(value => {
  return value > 6;
});
console.log(index2); // 3

findIndex() 方法是可以通过 Objecy.is(NaN) 来识别出 NaN 的。

console.log([NaN].findIndex(val => Object.is(NaN, val)));
// 0

fill()

fill 方法使用给定值,填充一个数组

参数可传一共三个

后两个参数可以不传,视为所有元素都是被填充元素。

let arr = [1, 2, 3];
console.log(arr.fill(3)); // [3, 3, 3]

let array = [1, 2, 3];
console.log(arr.fill(5, 1, 2)); // [1, 5, 3]

keys()、values() 和 entries()

ES6 提供的新的方法 用来遍历数组 。返回的都是一个遍历器对象,可以用 for...of 循环进行遍历。

keys() 实例方法,就是为了遍历数组的 key

let arr = ['x', 'y', 'z'];
for (let key of arr.keys()) {
    console.log(key);
}
// 0
// 1
// 2

values() 实例方法,是为了遍历数组的值

let arr = ['x', 'y', 'z'];
for (let val of arr.values()) {
  console.log(val);
}
// 'x'
// 'y'
// 'z'

// 相当于普通的循环遍历
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}
// 'x'
// 'y'
// 'z'

entries() 实例方法,是对键值对的遍历。 在这里还用到了数组的解构赋值

let arr = ['x', 'y', 'z'];
for (let [key, value] of arr.entries()) {
  console.log(key, value);
}
// 0 'x'
// 1 'y'
// 2 'z'

上面代码中的 [key, value],其实就是遍历 arr.entries() ,并对其中一个值进行解构赋值

可以来看看不使用 for...of 的写法,需要自己手动调用遍历器对象的 next 方法,然后.value 去取到相应值,为了方便这里就写在一起了

let arr = ['x', 'y', 'z'];
// keys()
let keys = arr.keys();
console.log(keys.next().value); // 0
console.log(keys.next().value); // 1
console.log(keys.next().value); // 2
// values()
let values = arr.values();
console.log(values.next().value); // 'x'
console.log(values.next().value); // 'y'
console.log(values.next().value); // 'z'
// entries()
let entries = arr.entries();
console.log(entries.next().value); // [0, 'x']
console.log(entries.next().value); // [1, 'y']
console.log(entries.next().value); // [2, 'z']

includes()

includes() 实例方法,就是用来做一个判断,表示某个数组是否包含给定过的值,与字符串的 includes 方法类似。

let arr = ['x', 'y', 'z', undefined, NaN];
console.log(arr.includes('x')); // true
console.log(arr.includes('1')); // false
console.log(arr.includes(undefined)); //true
console.log(arr.includes(NaN)); // true

includes() 方法的第二个参数表示搜索的起始位置

let arr = ['x', 'y', 'z', undefined, NaN];
console.log(arr.includes('x', 1)); // false

上面的例子表示,检索数组从下标 1 开始检索,所以第一个参数 'x',就检索不到啦。

flat(),flatMap()

flat() 就是简单来说就是 数组的扁平化,如果数组内嵌套数组,那就可以将其转为单层数组。

let arr = [1, 2, 3, [4]];
console.log(arr.flat()); // [1, 2, 3, 4]

当然,默认情况下,只会偏平一层,如果传入参数就可以偏平自己需要的层数。

let arr = [1, 2, [3, [4, [5]]]];
console.log(arr.flat()); // [1, 2, 3, [4, [5]]]
console.log(arr.flat(2)); // [1, 2, 3, 4, [5]]
console.log(arr.flat(3)); // [1, 2, 3, 4, 5]

注意

如果你需要无论多少层都将其转化为一层,使用正无穷(Infinity)作为参数即可。

如果数组有空位flat() 函数则会将空位跳过

let arr = [1, [2, [3, [4, [5, [6]]]]]];
console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5, 6]

let array = [1, , 3, , 5];
console.log(array.flat()); // [1, 3, 5]

flatMap() 实例方法,可以理解为,对数组进行 map 操作,然后对返回值组成的数组执行 flat() 方法。该实例方法,返回一个新的数组,不会改变原数组。

let arr = [1, 2, 3, [4]];
let array = arr.flatMap((item) => item * 2)
console.log(array); // [2, 4, 6, 8]

注意

该方法只能展开一层,无法多层展开,有兴趣的,可以去验证一下。