前言
大家都知道,数组和对象是两种不同的数据结构,虽说在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个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享