Skip to content

集合引用类型

Object

创建对象的方式:

  1. new Object()

注意:使用对象字面量定义对象并不会实际调用Obect() 构造函数

调用属性的方式:

  1. 通过点方式来调用
  2. 通过[ ]方式来调用

[ ]的好处:可以通过变量访问属性,并且如果属性名包含会导致语法的错误的字符时,可以使用[ ]

Array

创建方式:

  1. new Arrary( )
  2. [ ]

new Array方式创建数组,如果传入数值参数n,则数组长度为n。 如果传入多个字符串,或数值,则创建相应的数组。因此容易产生错误。

js
 let a = new Array(3);
 let b = new Array(2, 3, 5, 6);
 console.log(a);//[empty × 3]
 console.log(b);//[2, 3, 5, 6]

注意:使用数组字面量定义数组并不会实际调用Array() 构造函数;

from()和of()方法

from()将类数据转换为数组

of( )将一组参数转换为数组实例

数组空位

for in 遍历空位数组无法识别空位,但数组长度是正确的

js
let a = [1, , , 2];
for (const item in a) {
console.log(item); // 0  3
}

for( ) 和for of 都会将空位字符遍历为undefined

js
let a = [1, , , 2];
for (let i = 0; i < a.length; i++) {
console.log(a[i]);
}

length

length属性是可以修改的,legth的值决定数组元素的个数。

检测数组

js
if (a instanceof Array) {
​      console.log(true);
​} 

if (Array.isArray(a)) {
console.log(true);
}

转换方法

valueOf( )返回数组本身,仍然是数组

toString() 返回以逗后隔开每一个元素的字符串

toLocaleString() 返回以逗后隔开每一个元素的字符串

join(相隔符 )返回以相应符号隔开元素的字符串

栈方法

push( )可以传入任意多个参数,在数组的末尾添加值,返回新数组的长度

pop( ) 删除最后一项,并返回这一项

队列方法

shift( )删出第一项,并返回这一项

unshift( )可以传入任意多个参数,在数组的开头添加值,返回新数组的长度

排序方法

sort( )

js
//升序排列
let a = [1, 5, 2, 4, 15];
function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1
    } else {
        return 0
    }
}
a.sort(compare);
console.log(a); //[1, 2, 4, 5, 15]  升序排列
//降序排列
let a = [1, 5, 2, 4, 15];

function compare(value1, value2) {
    if (value1 < value2) {
        return 1;
    } else if (value1 > value2) {
        return -1
    } else {
        return 0
    }
}
a.sort(compare);
console.log(a);// [15, 5, 4, 2, 1] 降序排列

比较函数返回值 :大于0,value1排在value2的后面,等于零,不变。小于零,value1应该排在value2的前面。

reverse( ):返回反转数组,并且改变原数组

搜索和位置方法

严格相等

indexof( ) 从头匹配相应元素,参数一为要匹配的元素,参数二为从当前下标开始

lastIndexof( ) 从末尾向前匹配相应元素,参数一为要匹配的元素,参数二为从当前下标开始

includes( )es7新增方法 从头匹配是否存在相应元素,参数一为要匹配的元素,参数二为从当前下标开始 ,返回布尔值

注意;匹配的规则为全等(===)

引用类型只有指向同一个内存地址,才会相等。全等和不全等都是这个规则。

下面的例子中people数组中无法匹配到person对象的原因:对象是引用类型,person对象和people中的第一个元素只是两个对象的值相等,他们是两个不同的对象,而全等对于引用类型来说是指向同一个对象,因此people中匹配person对象是无法匹配到的。

js
let person = {
    name: 'nike'
};
let people = [{
    name: 'nike'
}];
let morepeople = [person];
console.log(people.indexOf(person)); //-1
console.log(morepeople.indexOf(person)); //0
console.log(people.includes(person)); //false
console.log(morepeople.includes(person)); //true
断言方法

断言函数接受三个参数 :元素,索引 ,数组本身

find( ) 从头开始匹配,匹配到第一个符合的元素之后不在遍历。返回第一个匹配的元素;

findIndex( ) 从头开始匹配,匹配到第一个符合的元素之后不在遍历。返回第一个匹配的元素的索引值;

js
const people = [{
    name: 'wang1',
    age: 15
}, {
    name: 'matong',
    age: 23
}];
console.log(people.find((element) => element.age > 20)); //{name: 'matong', age: 23}
console.log(people.findIndex((element) => element.age > 20)); //1
js

let arr = [2, 5, 6, 3, 7, 8];
arr.find((element, index, array) => {
    console.log(element);
    console.log(index);
    console.log(array);
    return element == 5;
});
//输出结果
 2
 0
(6) [2, 5, 6, 3, 7, 8]
 5
 1
 (6) [2, 5, 6, 3, 7, 8]

迭代方法

every( ) 对数组每一样都运行传入的函数,如果都返回true,则这个方法返回true

some( )对数组每一样都运行传入的函数,只要有一项返回true,则这个方法返回true

filter( )对数组每一样都运行传入的函数,返回true的项组成一个新数组

map( )对数组每一样都运行传入的函数,返回由每次函数调用的结果构成的数组;

foreach( ) 遍历数组,相当于for循环

都可以传入三个参数:数组元素,数组索引,数组本身 所有方法都不改变原来数组

js
 const numbers = [1, 2, 3, 4, 5, 2, 1];
let numevery = numbers.every((item, index, array) => item > 1);
console.log(numevery);
console.log(numbers.some((item) => item > 2));
console.log(numbers.filter((item) => item > 2));
console.log(numbers.map((item) => item * 2));
console.log(numbers);

归并方法

reduce( ) 和reduceRight( )都可以插入两个参数,一是归并函数,二是归并初始值

js
const numbers = [1, 2, 3, 4, 5, 2, 1];
 let sum = numbers.reduceRight((prev, cur, index, array) => prev + cur, 0);
console.log(sum);//18

join()

join() 方法将数组作为字符串返回。

元素将由指定的分隔符分隔。默认分隔符是逗号 (,)。

splice(start,deleteCount,item1,item2)

修改原数组,可以删除,添加,修改数组内容

Map

es6之后新增的集合类型,与Object类型不同,Map可以使用任意数据类型作为键,包括函数。

基本用法:

js
const m = new Map([
    ['key1', 'value1'],
    ['key2', 'value2'],
    ['key3', 'value3']
]); //传入可迭代对象,初始化Map集合
m.set('key4', 'value4'); //添加键值对
m.delete('key1'); //删除key1键值对,返回布尔值
m.clear(); //删除全部键值对

顺序和迭代

和Object类型的一个主要差异是,Map维护键值对的插入顺序。因此Map类型可以通过entries() 或Symbol.iterator方法取得迭代器,进行遍历。

js
const m = new Map([
['key1', 'value1'],
['key2', 'value2'],
['key3', 'value3']
]);
console.log(m.entries === m.entries()); //也可以使用m[Symbol.iterator],不调用方法也可以迭代,内部自动调用entries()方法
for (const pair of m) {
console.log(pair);  //(2) ['key1', 'value1']
				    //(2) ['key2', 'value2']
				    //(2) ['key3', 'value3']
}

也可以通过forEach()方法传入回调进行迭代

js
m.forEach((val, key) => console.log(`${key} -> ${val}`));
//key1 -> value1
//key2 -> value2
//key3 -> value3

keys( ),values()方法分别返回出入顺序生成键和值得迭代器。

js
    for (const key of m.keys()) {
        console.log(key);
    }
    for (const value of m.values()) {
        console.log(value);
    }

键和值在迭代器遍历时时可以修改的,但映射内部是不可能以修改的。但可以修改键和值对象中的内部属性,因为这并不影响他们在映射实例中的身份。

js
    const m = new Map([
        ['key1', 'value1'],
    ]);
    for (let key of m.keys()) {
        key = 'newkey1';
        //key在迭代器中修改了,但Map中的key没有改
        console.log(key); //newkey1
        console.log(m.get('newkey1')); //undefined
    }
js
	//可以修改对象中的属性
    const obj = {
        id: 1
    };
    const m = new Map([
        [obj, 'value1'],
    ]);
    for (let key of m.keys()) {
        key.id = 'newkey';
        console.log(key);//{id: 'newkey'}
        console.log(m.get(obj)); //value1
    }
    console.log(obj);//{id: 'newkey'}

Map和Object的比较

  1. 同样的内存Map可以存储更多的键值对
  2. 如果有大量的插入操作,Map的性能更高
  3. 在查找速度方面,有大量的查找存在Object性能更高一点
  4. Map的删除性能更高

weakMap

es6中新增,弱映射类型,可以使用get(),set(),has(),delete()方法,区别在于weakMap的键必须是object类型,不能是非对象类型的数据。

  1. 初始化时只要有一个键不是对象类型,就会报错,导致整个weakMap初始化失败。
  2. 原始值可以先包装成对象再用作键

Set

Set与Map相似,像是加强了的Map

添加元素的方法为add( ),而Map为set( )方法。其他的方法和属性与Map类似。

js
const m = new Set([
    'value1',
    'value2'
]);
m.add('value3');