Set、Map、类数组,傻傻区分不清楚?

前言

大家都知道,数组和对象是两种不同的数据结构,虽说在js数据类型中都属于Object,但是还是有一定的区别,通过字面量以及isArray、instanceof等方法,我们很好区分这两者。由于使用场景的原因js中衍生了很多类似的数据结构,这些数据结构和数组、对象非常接近,使用过少或基础不牢固的同学(没错,说的是我)对他们的概念、用法不是很清晰,并且很容易混淆。今天在这里对这一类的数据结构做一个总结,让我们能明确区分他们的使用场景和用法。

类数组

在js中,具有length属性,但却不能使用数组类的方法的数据结构被称为类数组。

arguments

arguments是一个可表示传递给函数的参数的类数组对象,所有非箭头函数都可以使用。

function fun(a, b) {
//Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
 console.log(arguments)
 //1
 console.log(arguments[0])
}
fun(1,2); 

arguments包含一个callee属性,该属性可指向参数所属的当前执行函数;

其他

NodeList:节点的集合,通常是某些方法属性返回的实时集合。如Node.childNodes或document.querySelectorAll方法返回的标签、节点。

HTMLCollection:表示一个包含了元素的通用集合(根据文档流顺序展示);

其他符合类数组概念的数据结构;

剩余参数

在ES6中,可以使用剩余参数语法来表示一个不定量的参数,这个参数为数组,以三个点为前缀。

function(...args) {
} 

和arguments的区别:

  • 剩余参数表示无对应形参的实参,arguments对象表示传给函数的所有实参;
  • arguments是类数组,剩余参数是数组,具有数组的属性和方法;
  • 剩余参数没有arguments自身的属性;

剩余参数语法可以用来展开数组和对象

//展开数组
//123
console.log(...[1,2,3]);

//展开对象,必须放在一个对象内
//{a: 1, b: 2, c: 3}
console.log({...{a:1,b:2,c:3}}); 

通过展开语法可以复制、合并数组;字符串转数组(字符串可看作类数组,通过展开运算符直接展开);类数组转换数组;复制对象、和解构赋值结合使用等等。

Set

Set是一种特殊的对象,是一系列无序、无重复值的数据集合,无字面量写法,通过Set构造函数的实例创建。

const s = new Set(); 

Set的方法和属性

Set.add() 在Set的尾部添加一个元素,可连续调用:

const s = new Set();
s.add(a).add(1).add(2); 

Set.has() 检测是否包含某个值的方法,返回一个布尔值

const s = new Set();
s.has(1); 

Set.delete() 删除指定值

const s = new Set();
s.delete(1); 

Set.clear() 删除所有值,清空set;

const s = new Set();
s.clear(); 

Set.forEach() 按照成员添加时的顺序进行遍历,键和值相等;

const s = new Set();
//它有两个参数第一个是回调,第二个表示this指向;
s.forEach(function(value,key,set){// value与key相等,set为原set;console.log(value,key,set)
},windows) 

Set.entries() 返回一个新的迭代器对象,包含所有Set值的数组,键和值相等;

const s = new Set();
s.add(1).add(2);
const i = s.entries();

for (const entry of i) {console.log(entry);//[1, 1]//[2, 2]
} 

Set.size() 表示set的长度,类似于数组的length;

const s = new Set();
//0
s.size; 

Set的用法及使用场景

添加不同参数的形式创建Set:

//数组
const s = new Set([1,2,3]);
console.log(s);//Set(3) {1, 2, 3}

//字符串
const s = new Set("abc");
console.log(s);//Set(3) {a, b, c}

//类数组
function fun() {const s = new Set(argument);console.log(s);//Set(3) {1, 2, 3}
}
fun(1,2,3)

//Set
const s = new Set("abc");
const s1 = new Set(s);
console.log(s1);//Set(3) {a, b, c} 

使用场景:

  • 字符串或数组去重;
  • 仅遍历,不需要数组下标访问时;
  • 使用Set自身的方法和属性时;

注意:Set中判断成员值重复是通过===,特殊的是在Set中NaN被认为与NaN重复(Map同理);

Map

Map是一种键值对的集合,和普通对象非常接近区别是对象的键一般是字符串,Map的键任何类型的数据都可以;通过Map构造函数实例创建;

let m = new Map();
m.set(key,value); 

Map的方法和属性

Map.set() 在Map中添加一组指定键关联的值:

const m = new Map();
//Map(3) {"a" => 1, "b" => 2, "c" => 3}
m.set("a",1).set("b",2).set("c",3); 

Map.get() 返回Map中指定键的值,没有则返回undefined

//1
m.get("a"); 

Map.delete() 删除指定键的值,返回布尔值

//true
m.delete("a"); 

Map.clear() 删除所有值,清空Map;

m.clear(); 

Map.forEach() 按照成员添加时的顺序进行遍历,执行回调;

const m = new Map();
//它有两个参数第一个是回调,第二个表示this指向;
m.forEach(function(value,key,Map){console.log(value,key,Map)
},windows) 

Map.entries() 返回一个新的迭代器对象,包含所有Map键和值的数组,以插入顺序排列;

const m = new Map();
m.set('a', 1);
m.set('b', 2);
const i = m.entries();
console.log(i.next().value);
// expected output: ["a", 1] 

Map.size() 表示Map的长度,类似于数组的length;

const m = new Set();
//0
m.size; 

Map的用法及使用场景

添加不同参数的形式创建Map:

//数组,必须是二维数组,键和值对应
const m = new Map([["a",1],["b",2]]);
console.log(m);//Map(2) {"a" => 1, "b" => 2}

//Set,必须键和值都有
const s = new Set([["a",1],["b",2]]);
const m = new Map(s);
console.log(m);//Map(2) {"a" => 1, "b" => 2}

//Map
const m = new Map([["a",1],["b",2]]);
const m1 = new Map(m);
console.log(m);//Map(2) {"a" => 1, "b" => 2} 

使用场景:

  • 字符串以外的值做key;
  • 复制Map;
  • 只需要键值对时可使用Map;
  • 使用Map自身的方法和属性时;
  • 当模拟现实世界实体时,如人、物等使用对象,字面量表示比较合适;

写在最后

js因其弱类型语言的特点,数据类型之间转换非常容易、灵活,它的标准内置对象及所携带的方法和属性非常丰富,熟练的掌握它们才能根据业务场景灵活的应用。

最后

最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

你可能感兴趣的:(javascript,前端,开发语言)