ES6

ES6之数组的扩展

2019-11-26  本文已影响0人  我写的代码绝对没有问题

在进入es6之数组的扩展这篇学习前,先了解下数组的基础内容,这里大概总结下,以便自己今后复习:

数组的创建方式:
  1. 字面量方法(常用)
var arr = [1,2,3];

2.使用构造函数创建

var arr = new Array(); //创建一个空数组[]
 
var arr = new Array(3); //创建一个长度为3的数组(数组项都为undefined)
 
var arr = new Array('小万',18,'男' ); //创建数组并写入数组元素 ['小万',18,'男']

3.创建数组对象

var stu=new Array();                                                                                                
stu[0]="小明";                                                                                                       
stu[1]=18;                                                                                                           
stu[2]="男";               
 //创建数组并写入数组元素 ['小明',18,'男']
数组的方法:

会改变原数组的:(这里列举一些常用的)

arr2 = [13, 24, 51, 3];
console.log(arr2.sort());  // [13, 24, 3, 51]
console.log(arr2);   // [13, 24, 3, 51](元数组被改变)

为了解决上述问题,sort() 方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。以下就是一个简单的比较函数:

function compare(value1, value2) {
  if (value1 < value2) {
  return -1;
 } else if (value1 > value2) {
   return 1;
 }else{
   return 0;
  }
}
  arr2 = [13,24,51,3];
  console.log(arr2.sort(compare));  // [3,13,24,51] 

sort() 只能对数组成员是相同位数的排序
sort(function(a,b){return a-b;} 从小到大
sort(function(a,b){return b-a;} 从大到小

- find()
这个方法是遍历查找数组里面第一个满足条件的值,并将这个值返回回来,该方法有两个参数:
第一个是数组每一项都会执行的回调函数,这个函数有三个参数,第一个是数组的每一项,第二个是数组每一项的下表索引,第三个就是遍历的原数组
第二个是回调时this的指向对象

[ES6之数组的扩展]

扩展运算符

扩展运算符(spread)是三个点(...),用于将数组转为逗号分隔的参数序列

如: ...[1,2,3] => 1,2,3 //只限一维转换,这种转换只有放进函数中调用才有意义,不能单独存在

    function plus(x,y){
        return x+y;
    }

    plus(...[3,7]);
    //10
    plus(3,...[7])
    plus(...[3],7)
    //可以灵活的置于函数参数中任意位置,只要根据传进的数据进行解析即可。
    
    //Array原生push方法(可向数组末尾添加一个或多个元素,顺序添加,且不创建新数组,直接修改原数组)
    let arr = [1,2,3];
    arr.push(4,5); //直接传参
    arr // [1,2,3,4,5]

    //使用扩展的方式:传入一个数组,进行拼接
    arr.push(...[6,7,8]);
    arr //[1,2,3,4,5,6,7,8]
  1. 复制数组/浅拷贝
    数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。
const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]
//输出a1,发现a1改变了。

上面代码中,a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。

ES5 只能用变通方法来复制数组:

const a1 = [1, 2];
const a2 = a1.concat();

a2[0] = 2;
a1 // [1, 2]

上面代码中,a1会返回原数组的克隆,再修改a2就不会对a1产生影响。
扩展运算符提供了复制数组的简便写法:

const a1 = [1, 2];

// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
//以上两种写法,都是a2对a1的克隆。
  1. 合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

// ES5 的合并数组
arr1.concat(arr2, arr3);

// ES6 的合并数组
[...arr1, ...arr2, ...arr3]

// 都返回[ 'a', 'b', 'c', 'd', 'e' ]
  1. 结合解构赋值,生成剩余数组 --- 扩展运算符只能置于参数最后
let [one,...rest] = [1,2,3,4,5];
one // 1
rest // [2,3,4,5]
  1. 扩展字符串成数组 --- 'hello'.split('')也可以实现
[...'hello']
// [ "h", "e", "l", "l", "o" ]

5.实现了Iterator接口的对象均可以使用扩展运算符转化成真正的数组(关于Iterator下次再写)

function convert2Arr(){
    return [...arguments];
}
        
let result = convert2Arr(1,2,3,4,5);
result // [1,2,3,4,5]

Array.from()

用于将类数组对象、可遍历的对象转为真正的数组(类数组对象特征:属性为非负整数、存在length属性、length>=0)

下面是一个类似数组的对象,Array.from将它转为真正的数组:

//类数组对象
let array = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3 //因为length不能动态改变,随意赋值,最后得到的数组长度就是其值
};

// ES5的写法
var arr1 = [].slice.call(array ); // ['a', 'b', 'c']

// ES6的写法
let arr2 = Array.from(array ); // ['a', 'b', 'c']
//类数组对象
let obj = {
    0:'hello',
    1:'world',
    4:'outof bounds data',
    length:3   //因为length不能动态改变,随意赋值,最后得到的数组长度就是其值
}
Array.from(obj);
// ["hello", "world", undefined]
//根据属性名对应到数组的index,超过length部分舍弃。没有对应的属性,置为undefined
//实现了Iterator接口的数据结构
let str = 'babe';
Array.from(str);
// ["b", "a", "b", "e"]
[...str]
// ["b", "a", "b", "e"]
//嗯,感觉现在JavaScript向着更幸福的方向发展了,条条大路通罗马。

Array.of()

Array.of方法用于将一组值,转换为数组。

存在的意义是替代以构造函数的形式创建数组,修复数组创建因参数不一致导致表现形式不同的伪bug.

Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。

Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]

Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。

数组实例的find()和findIndex()

Array.prototype.find() 和 Array.prototype.findIndex()方法 --常用

[1, 4, -5, 10].find((n) => n < 0)
// -5
[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

find()和findIndex()这两个方法都可以使用indexOf替代,只是比indexOf更精细(可以查找NaN所在位置)

数组实例的 includes()

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值。与字符串的includes方法类似
[1, 2, 3].includes(4)     // false
[1, 2, NaN].includes(NaN) // true

没有includes之前,我们通常使用数组的indexO方法,检查是否包含某个值,使用indexOf()方法如果存在会返回查找值的位置,找不到会返回-1;但是这有个问题就是,如果查找的值碰巧是NaN呢,就会导致误判:

[NaN].indexOf(NaN)
// -1

indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。

es6关于数组的扩展还有fill()、entries()、keys() 、values()、flat()、flatMap() 等因为不常用就不一一举例了。

上一篇 下一篇

猜你喜欢

热点阅读