ES6 数组

783 阅读9分钟

1.数组声明

(1)创建数组

使用对象方式创建数组

new Array(1, 'huihui');

使用字面量创建数组

const array = [1, 'huihui];

数组是引用类型可以使用const声明并修改它的值

const array = [1, 'huihui'];
array.push('cute');

使用原型的length属性可以获取数组元素数量

const array = [1, 'huihui'];
console.log(array.length)

数组可以设置任何值,下面是使用索引添加数组

let arr = ['huihui'];
arr[1] = 18;

下面是直接设置3号数组,会将1/2索引的数组定义为undefined

let arr = ['huihui'];
arr[3] = 19;
console.log(a[1])    // undefined
console.log(a[2])    // undefined

声明多个空元素的数组

let arr = new Array(3);
console.log(arr.length)    // 3
console.log(arr)    // [empty × 3]

(2)Array.of

使用Array.of 与 new Array 不同的是设置一个参数时不会创建一个空元素的数组

let arr = Array.of(3);
console.log(arr)    // [3]

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

(3)类型检测

console.log(Array.isArray(['huihui', 18]));    // true
console.log(Array.isArray(9))    // false

2.类型转换

可以将数组转换为字符串 也可以将其他类型转换为数组

(1)字符串

使用.toString()将数组转换为字符转

console.log(([1, 2, 3]).toString());    // 1,2,3

使用函数String转换为字符串

console.log(String([1, 2, 3]))

使用join连接字符串

consoe.log([1, 2, 3].join('-'))    // 1-2-3

(2)Array.from

使用Array.from可将类数组转化为数组 类数组指包含length属性或可迭代的对象

let str = '张小慧';
console.log(Array.from(str))    // ["张", "小", "慧"]

为对象设置length属性后也可以转化为数组,但要下标为数值或数值字符串

let str = {
  0: 'zxh',
  '1': 18,
  length: 2
};
console.log(Array.from(str)); //["zxh", 18]

3.展开语法

(1)数组合并

使用展开语法合来合并数组要比concat更加简单,使用...可将数组展开为多个值

let a = [1, 2, 3];
let b = ['a', ...a];
console.log(b)    // ['a', 1, 2, 3]

(2)函数参数

使用展开语法可替代arguments来接收任意数量的参数。

let hd(...args){
    console.log(args);
}
hd(1, 2, 3);    // [1, 2, 3]

使用展开语法也可用于接收部分参数

let hd(name, ...args){
    console.log(args);
}
hd("huihui", 1, 2, 3);    // [1, 2, 3]

4.解构赋值

解构是一种更简单的赋值特性,可以理解为分解一个数据的结构

(1)基本使用

let [name, age] = ['huihui', 19];
console.log(name, age)    // huihui 19

结构赋值数组

function test() {
    return ['huihui', 19]
}
let [name, age] = test();
console.log(name, age)    // huihui 19

剩余解构指用一个变量来接收剩余参数

let [a, ...b] = ['test', 1, 2, 3, 4];
console.log(b)    // [1, 2, 3, 4]

字符串解构

const [...test] = 'zhangxiaohui';
console.log(test);    // ["z", "h", "a", "n", "g", "x", "i", "a", "o", "h", "u", "i"]

(2)简洁定义

只赋值部分变量

let [, age] = ['huihui', 18];
console.log(age)    // 18

使用展开语法获取多个值

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

(3)默认值

为变量设置默认值

let [name, age = 18] = ['huihui'];
console.log(age);    // 18

(4)函数参数

函数参数的使用

function test([a, b]) {
    console.log(a, b)
}
test(['huihui', 18])

5.管理元素

(1)基本使用

push

压入元素,直接改变原数组,返回值为数组元素的数量

let test = [1];
test.push(2);
console.log(test)    // [1, 2]
let test = [{name: 'huihui'}];
test.push({name: 'dudu'});
console.log(test);    // [{name: 'huihui'}, {name: 'dudu'}]
pop

从末尾弹出元素,直接改变原数组,返回值是弹出的元素

let test = [1, 2];
console.log(test.pop())    // 2
let test = [{name: 'huihui'}]; 
console.log(test.pop());    // ['huihui']
shift

从数组前面取出一个元素

let test = ['huihui', 19];
console.log(test.shift())    // 'huihui'
let test = [{name: 'huihui'}]; 
console.log(test.shift());    // {name: "huihui"}
unshift

从数组前面添加元素

let test = [2, 3];
console.log(test.unshift(0, 1))    // 4
console.log(test)    // [0, 1, 2, 3]
let test = [{name: 'huihui'}];
test.unshift({name: 'dudu'});
console.log(test);    //[{name: "dudu"}, {name: "huihui"}]
fill

使用fill数组填充元素

console.dir(Array(4).fill("huihui")); //["huihui", "huihui", "huihui", "huihui"]

指定填充位置

console.log([1, 2, 3, 4].fill("huihui", 1, 2)); //[1, "huihui", 3, 4]
slice

使用slice方法从数组中截取部分元素注意是截取,这里只能取到截取的元素,并不会改变原数组不传第二个参数时截取到数组最后的元素。

arr.slice(start, end) // 表示从从start位置开始截取,从end-1个位置结束截取

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

不设置参数是获取所有元素

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

使用splice方法可以添加、删除、替换数组中的元素,会对原数组进行改变,返回值为删除的数量

删除数组元素的第一个参数为从哪开始删除,第二个参数为删除的数量,第三个参数为在删除位置添加的元素

删除

let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(1, 3)); //返回删除的元素 [1, 2, 3] 
console.log(arr); //删除数据后的原数组 [0, 4, 5, 6]

添加/替换

let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.splice(1, 3, 'huihui', '19')); //[1, 2, 3]
console.log(arr); //[0, "huihui", "19", 4, 5, 6]

(2)合并拆分

join

使用join连接成字符串

let arr = ['huihui', 19];
console.log(arr.join('-'))    // "huihui-19"
split

使用split 方法用于将字符串分割成数组,类似join 方法的反函数

let str = 'huihui-19';
console.log(str.split("-"))    // ["huihui", "19"]
concat

concat 方法用于连接两个或多个数组,元素是值类型的是复制操作,如果是引用类型还是指向同一对象

let array = ["huihui",  18];
let array1 = [1, 2];
let array2 = [3, 4];
console.log(array.concat(array1, array2));    // ["huihui", 18, 1, 2, 3, 4]=

也可以使用扩展语法实现连接

console.log([...array, ...array1, ...array2])
copyWithin

使用copyWithin从数组中复制一部分到同数组中的另外位置

(3)查找元素

indexOf

使用indexOf从前向后查找元素出现的位置,如果找不到返回-1

let arr = [7, 3, 2, 8, 2, 6];
console.log(arr.indexOf(2)); // 2 从前面查找2出现的位置

注意: indexOf 是 === 严格类型约束

let arr = [7, 3, 2, '8', 2, 6];
console.log(arr.indexOf(8)); // -1

第二个参数用于指定查找开始位置

let arr = [7, 3, 2, 8, 2, 6];
//从第二个元素开始向后查找
console.log(arr.indexOf(2, 3)); //4
lastIndexOf

从后向前找元素出现的位置,如果找不到返回-1

let arr = [7, 3, 2, 8, 2, 6];
console.log(arr.lastIndexOf(2)); // 4 从后查找2出现的位置

第二个参数用于指定查找的位置

let arr = [7, 3, 2, 8, 2, 6];
//从第五个元素向前查找
console.log(arr.lastIndexOf(2, 5));

//从最后一个字符向前查找
console.log(arr.lastIndexOf(2, -2));
includes

使用includes查找字符串返回值是布尔值

let arr = [7, 3, 2, 6];
console.log(arr.includes(6)); //true

includes 函数实现原理

function includes(array, item) {
  for (const value of array)
    if (item === value) return true;
    // 注意这里是跳出for 循环返回false
  return false;
}

console.log(includes([1, 2, 3, 4], 3)); //true
find

find 方法找到后会把值返回 如果找不到返回值为undefined. 注意: 返回第一次查找的值,不再继续查找。

let arr = ["huihui", "eva", "luna"];

let find = arr.find(function(item) {
  return item == "huihui";
});

console.log(find); //huihui

使用includes 不能查找引用类型,因为它们的内存地址是不相等的。

const user = [{ name: "李四" }, { name: "张三" }, { name: "huihui" }];
const find = user.includes({ name: "huihui" });
console.log(find);

find可以方便的查找引用类型

const user = [{ name: "李四" }, { name: "张三" }, { name: "huihui" }];
const find = user.find(user => (user.name = "huihui"));
console.log(find);
findIndex

findIndex 与 find 的区别是返回索引值,查找不到时返回-1

let arr = [7, 3, 2, '8', 2, 6];

console.log(arr.findIndex(function (v) {
	return v == 8;
})); //3
find原理
let arr = [1, 2, 3, 4, 5];
function find(array, callback) {
  console.log('callback', callback)
  for(const value of array) {
    if(callback(value) === true) return value
  }
  return undefined
}
let res = find(arr, function(item) {
  return item == 5
});
console.log(res)

(4)数组排序

reverse
let arr = [1, 4, 2, 9];
console.log(arr.reverse()); //[9, 2, 4, 1]
sort

使用排序函数从大到小排序,参数一与参数二比较,返回正数为降序负数为升序

let arr = [1, 4, 2, 9];

console.log(arr.sort(function (v1, v2) {
	return v2 - v1;
})); //[9, 4, 2, 1]
排序原理

快速排序

(5)循环遍历

for
forEach

forEach使函数作用在每个数组元素上,但是没有返回值 forEach不可以return

for/in

遍历时的key值为数组的索引

let lessons = [
  {title: '媒体查询响应式布局',category: 'css'},
  {title: 'FLEX 弹性盒模型',category: 'css'},
  {title: 'MYSQL多表查询随意操作',category: 'mysql'}
];

for (const key in lessons) {
    console.log(key);
}    // 0 1 2
for/of

与for/in不同的是for/of每次循环取其中的值而不是索引

let lessons = [
  {title: '媒体查询响应式布局',category: 'css'},
  {title: 'FLEX 弹性盒模型',category: 'css'},
  {title: 'MYSQL多表查询随意操作',category: 'mysql'}
];
for (const item of lessons) {
  console.log(item)
}
//  输出结果为:
{title: "媒体查询响应式布局", category: "css"}
{title: "FLEX 弹性盒模型", category: "css"}
{title: "MYSQL多表查询随意操作", category: "mysql"}

(6)迭代器方法

keys
let lessons = [
  {title: '媒体查询响应式布局',category: 'css'},
  {title: 'FLEX 弹性盒模型',category: 'css'},
  {title: 'MYSQL多表查询随意操作',category: 'mysql'}
];
console.log(lessons.keys())    // Array Iterator {} 为什么?为什么?
const array = ["huihui", "eva"];
const keys = array.keys();    // Array Iterator {}
console.log(keys.next());    // {value: 0, done: false}
console.log(keys.next());    // {value: 1, done: false}   
console.log(keys.next());    // {value: undefined, done: true} 

for(const key of array.keys()) {
    console.log(key)    // 0 1
}
values
const array = ["huihui", "eva"];
const keys = array.values();    // Array Iterator {}
console.log(keys.next());    // {value: 0, done: false}
console.log(keys.next());    // {value: 1, done: false}    
console.log(keys.next());    // {value: undefined, done: true}  

for(const key of array.values()) {
    console.log(key)    // 'huihui' 'eva'
}
entries

返回数组所有键值对

const arr = ["a", "b", "c",];
for (const [key, value] of arr.entries()) {
  console.log(key, value);
}
// 输出内容为
0 "a"
1 "b"
2 "c"

(7)扩展方法

every

every 用于递归的检测元素,要所有元素操作都要返回真结果才为真。 第一个参数为元素,第二个参数为索引,第三个参数为原数组。

some

some函数用于递归的检测元素,如果有一个返回true,表达式结果就是真。 第一个参数为元素,第二个参数为索引,第三个参数为原数组。

filter

filter可以过滤数据中的元素。

map

map映射可在数组的所有元素上应用函数,用于映射出新的值

reduce
arr.reduce(callback, [initialValue])

callback 执行数组中每个值的函数,包含四个参数

  1. pre: 上一次调用返回的值,或者是提供的初始值
  2. cur: 数组中当前被处理的元素
  3. index: 当前元素在数组中的索引
  4. array: 调用reduce的数组
let arr = [1, 2, 3, 4];
let sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
})
console.log(arr, sum);

// 输出结果为
1 2 1
3 3 3 2
3 6 4 3
[1, 2, 3, 4] 10

数组的长度为4,但是reduce函数循环了3次。因为index是从1开始的

let arr = [1, 2, 3, 4];
let sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
}, 0)
console.log(arr, sum);

// 输出结果为
0 1 0
1 2 1
3 3 2
6 4 3
(4) [1, 2, 3, 4] 10

数组长度为4,reduce函数循环了4次。因为设置了pre初始值为0

(1) 计算数组中每个元素出现的次数

names = ['alice', 'bob', 'tiff', 'alice']
let nameNum = names.reduce((pre, cur) => {
        console.log('pre 的值为:', pre)
        console.log('cur的值为:', cur)
        if(cur in pre) {
                pre[cur]++
        } else {
                pre[cur] = 1
        }
        console.log(pre)
        return pre
}, {})
console.log(nameNum)    // {alice: 2, bob: 1, tiff: 1}

(2)数组去重

let arr = [1, 2, 3, 4, 4, 1];
let newArr = arr.reduce((pre, cur) => {
        if(!pre.includes(cur)){
                return pre.concat(cur)
        } else {
                return pre
        }
},[])
console.log(newArr)    // [1, 2, 3, 4]

(3)将二维数组转化为一维数组

let arr = [[0,1], [2, 3], [4, 5]];
let concatArr = arr.reduce((pre, cur) => {
        return pre.concat(cur)
},[])
console.log(concatArr)    // [0, 1, 2, 3, 4, 5]

(4)对象属性求和

let result = [
    {
        subject: 'math',
        score: 10
    },
    {
        subject: 'chinese',
        score: 20
    },
    {
        subject: 'english',
        score: 30
    }
];
let total = result.reduce((pre, cur) => {
        return pre + cur.score
}, 0)
console.log(total)    // 60

(8)数组应用

(1)清空数组的几种方法
(2)数组去重的几种方法

---- 未完待续