数组、Set和Map比较
- 都是JavaScript的数据结构
- Set是ES6提供的新的数据结构, 类似于数组, 但是它的成员是唯一的, 不能重复
- Map是ES6提供的新的数据结构, 本质上是键值对的集合(Hash 结构), 但是传统上只能用字符串当作键。这给它的使用带来了很大的限制,所有ES6中新增了Map数据结构, 它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
Array
- 创建数组
let arr = new Array(3); // 创建一个包含3项的数组
let names = new Array("张三"); // 创建一个包含1项, 值为“张三”的数组
let colors = ["red", "blue", "green"]; // 创建一个包含3个字符串的数组
let names = []; // 创建一个空数组
- 判断是不是数组
if(value instanceof Array){
}
instanceof操作符存在一个问题, 就是它假定只有一个全局执行环境, 如果网页中包含多个框架, 实际上就存在多个不同的全局执行环境, 如果从一个框架向另外一个框架传入一个数组, 那么传入的数组和框架的原生创建的数组分别具有各自不同的构造函数
怎么解决这个问题?
ECMAScript5新增了Array.isArray()方法
if(Array.isArray(value)){
}
- 数组长度
let colors = ["red", "blue", "green"];
colors.length;
注: 数组的length是可以修改的
colors.length = 2; //这个时候数组的长度就是2了
console.log(colors[2]); // undefined
- 数组转字符串
let colors = ["red", "blue", "green"];
console.log(colors.toString()); //red,blue,green
- 数组增加和删除元素
1.栈方法, 后进先出
let colors = new Array();
colors.push("red", "blud"); //[ 'red', 'blud' ] 数据入栈
colors.push("green"); //[ 'red', 'blud', 'green' ]
colors.pop(); // green出栈
console.log(colors); //[ 'red', 'blud' ]
2.队列方法, 先进先出
let colors = new Array();
colors.unshift("red", "green"); //[ 'red', 'green' ] 入队
let color = colors.shift();
console.log(color); //red 出队
console.log(colors);
- 数组排序
反转
let vals = [1, 2, 3, 4, 5];
vals.reverse();
console.log(vals);//[ 5, 4, 3, 2, 1 ]
升序排列
let vals = [3, 5, 1, 2, 4];
vals.sort(); //[ 1, 2, 3, 4, 5 ]
console.log(vals);
- 数组拼接
concat
1. 该方法会先创建当前数组的一个副本
2. 无参数的情况下, 直接返回副本, 有参数的情况下, 将参数中的数组元素添加到数组的尾部
let colors1 = ["red", "green"];
let colors2 = colors1.concat("yellow", ["black", "blue"]);
console.log(colors2); //[ 'red', 'green', 'yellow', 'black', 'blue' ]
- 数组截取
slice, 基于当前数组中的一项或多项创建一个新的数组
let colors1 = ["red", "green", "blue", "yellow", "black", "white"];
let colors2 = colors1.slice(1); //[ 'green', 'blue', 'yellow', 'black', 'white' ] //从下标为1的元素开始截取
let colors3 = colors1.slice(1, 3);//[ 'green', 'blue' ] //截取下标1到3但是不包含3
- 数组增、删、改
splice, 这个方法很强大, 根据传入的参数不同, 可以实现对数组进行增、删、改
删除: 2个参数, 从第几项开始删和删除几项
let colors = ["red", "green", "blue", "yellow", "black", "white"];
let removed = colors.splice(0, 1);
console.log(removed); //[ 'red' ]
console.log(colors);//[ 'green', 'blue', 'yellow', 'black', 'white' ]
插入: 3+个参数, 起始位置, 要删除几项(填0), 要插入的项(可以写多个参数)
let colors = ["red", "blue"];
colors.splice(1, 0, "yellow"); //[ 'red', 'yellow', 'blue' ]
colors.splice(1, 0, "black", "green"); //[ 'red', 'black', 'green', 'yellow', 'blue' ]
console.log(colors);
替换: 参数, 起始位置、要删除的项、要插入的项
let colors = ["red", "blue"];
colors.splice(1, 1, "yellow"); //[ 'red', 'yellow' ]
console.log(colors);
- 数组查找
indexOf()和lastIndexOf()
参数: 要查找的项、起点位置索引(可选)
indexOf() 从数组开头开始查找
lastIndexOf() 从数组的末尾开始查找
let colors = ["red", "green", "blue", "yellow", "black", "white"];
let index = colors.indexOf("blue");
let lastIndex = colors.lastIndexOf("white");
console.log(index, lastIndex); //2, 5
- 数组迭代
every
对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true, 否则返回false
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
return (item > 2);
});
console.log(everyResult); //false
some
对数组中的每一项运行给定函数,如果该函数只要有一项返回 true,则返回 true
var someResult = numbers.some(function(item, index, array){
return (item > 2);
});
console.log(someResult);
filter
对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组
var numbers = [1,2,3,4,5,4,3,2,1];
var result = numbers.filter(function(item, index, array){
return (item > 2);
});
console.log(result); //[ 3, 4, 5, 4, 3 ]
forEach
对数组中的每一项运行给定函数。这个方法没有返回值
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array){
// 执行某些操作
});
map
对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
var numbers = [1,2,3,4,5,4,3,2,1];
var result = numbers.map(function(item, index, array){
return item * 2;
});
console.log(result); //[ 2, 4, 6, 8, 10, 8, 6, 4, 2 ]
Set
- 创建Set
值不会重复
let set = new Set([1, 2, 3, 3, 4]);
set.add(4); //4已经存在, 不会添加
set.add(5); //5添加成功
console.log(set); //Set { 1, 2, 3, 4, 5 }
- Set的属性和方法
size, Set中元素的数量
let set = new Set([1, 2, 3, 3, 4]);
console.log(set.size); //Set的长度 4
添加和删除元素
let set = new Set([1, 2, 3]);
set.add(4);
console.log(set); //Set { 1, 2, 3, 4 }
set.delete(2);
console.log(set); //Set { 1, 3, 4 }
元素是否存在
let set = new Set([1, 2, 3]);
console.log(set.has(1)); //true
console.log(set.has(4)); //false
- 清空所有元素
let set = new Set([1, 2, 3]);
console.log(set); //Set { 1, 2, 3 }
set.clear(); //清空Set
console.log(set); //Set {}
- 遍历Set
4个遍历方法
Set.prototype.keys():返回键名的遍历器
Set.prototype.values():返回键值的遍历器
Set.prototype.entries():返回键值对的遍历器
Set.prototype.forEach():使用回调函数遍历每个成员
遍历
let set = new Set(['Java', 'Php', 'Node']);
由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。
// keys
for(let item of set.keys()){
console.log(item);
}
输出:
Java
Php
Node
// values
// Set 的默认遍历器生成函数就是它的values方法, 所以这里的values是可以省略的
for(let item of set.values()){
console.log(item);
}
或
for(let item of set){
console.log(item);
}
输出:
Java
Php
Node
// entries
for(let item of set.entries()){
console.log(item);
}
输出:
[ 'Java', 'Java' ]
[ 'Php', 'Php' ]
[ 'Node', 'Node' ]
//forEach
// 参数依次是 键值、键名、集合本身
set.forEach((value, key, set) => console.log(key + ' : ' + value))
Map
JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制,所有ES6中新增了Map数据结构, 它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const map = new Map();
const obj = {name: '张三'};
map.set(obj, 'zhang san is a man');
console.log(map.get(obj)); //zhang san is a man
- 创建Map
// 构造方法创建Map
const map = new Map([
['name', 'zhangsan'],
['des', 'zhangsan is a man']
]);
- 属性和方法
- size
成员总数
console.log(map.size); //2
- has
has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中
console.log(map.has('name')); //true
- set
set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
map.set('name', 'lisi');
- get
get方法读取key对应的键值,如果找不到key,返回undefined。
map.get('name');
- delete
delete方法删除某个键,返回true。如果删除失败,返回false。
map.delete('name');
- clear
clear方法清除所有成员,没有返回值。
map.clear()
- 遍历方法
Map.prototype.keys():返回键名的遍历器。
Map.prototype.values():返回键值的遍历器。
Map.prototype.entries():返回所有成员的遍历器。
Map.prototype.forEach():遍历 Map 的所有成员
const map = new Map([
['name', 'zhangsan'],
['des', 'zhangsan is a man']
]);
//keys
for(let key of map.keys()){
console.log(key);
}
输出:
name
des
//values
for(let val of map.values()){
console.log(val);
}
输出:
zhangsan
zhangsan is a man
//entries
for(let item of map.entries()){
console.log(item);
}
输出:
[ 'name', 'zhangsan' ]
[ 'des', 'zhangsan is a man' ]
for(let [key, value] of map.entries()){
console.log(key, value);
}
输出:
name zhangsan
des zhangsan is a man
// 等价于map.entries
for(let [key, value] of map){
console.log(key, value);
}
输出:
name zhangsan
des zhangsan is a man
forEach, 跟数组中的forEach用法一致
const map = new Map([
['name', 'zhangsan'],
['des', 'zhangsan is a man']
]);
map.forEach(function(value, key, map){
console.log(key, value);
});