ES6之数组的扩展

在进入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,'男']
数组的方法:
  • push()
  • pop()
  • shift()
  • unshift()
  • sort()
  • splice()
  • reverse()
  • find()
  • findIndex()
  • flat()
  • flatMap()
  • includes()
  • keys()
  • toString()
  • values()
  • copyWithin()
  • fill()
  • slice()
  • concat()
  • join()
  • indexOf()
  • lastIndexOf()
  • forEach()
  • map()
  • filter()
  • every()
  • some()
  • reduce()
  • reduceRight()

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

  • push() 将一个或多个元素添加到数组的末尾
    arrayObject.push(newelement1,...newelementX)

  • pop() 从数组中删除最后一个元素,并返回该元素的值(无参数)

  • shift() 删除原数组第一项,并返回删除元素的值,如果数组为空则返回 undefined(无参数)

  • unshift() 将参数添加到原数组开头,返返回数组的长度
    arryayObject.unshift(item1,item2....)

  • sort() 按升序排列数组项,即最小的值位于最前面,最大的值排在最后面
    在排序时,sort() 方法会调用每个数组项的 toString()转型方法,然后比较得到的字符串,以确定如何排序。即使数组中的每一项都是数值,sort()比较的也是字符串,因此会出现以下这种情况 :

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;} 从大到小

  • reverse() 反转数组项的顺序,将数组倒序输出(无参数)

  • splice() 删除.替换数组中某几项
    splice(m,n),从索引m开始删除n项
    splice(m) 从m开始全部删除
    splice(m,n,item1,item2....)

    不会改变原数组的

  • slice() 数组的截取
    slice(m,n) 从索引的m开始,不包含n
    slice(m)从索引m开始截取到结尾
    slice() 整个数组

  • concat() 数组的拼接

  • join() 将数组成员按照特定的字符连接成一个字符串
    1)不传递参数默认按逗号分开
    2)传参数,按参数拼接

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

  • indexOf()和lastIndexOf()
  • forEach()
  • map()
  • filter()
  • every()
  • some()
  • reduce()
  • reduceRight()

[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()方法 --常用

  • Array.prototype.find():用于找出第一个符合条件的数组成员,否则返回 undefined。
[1, 4, -5, 10].find((n) => n < 0)
// -5
  • Array.prototype.findIndex():用于找到第一条符合要求的数组位置,找到返回index,否则返回-1;
[1, 5, 10, 15].findIndex(function(value, index, arr) {
  return value > 9;
}) // 2

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

  • Array.prototype.indexOf():返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回 -1

数组实例的 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() 等因为不常用就不一一举例了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容