006 集合引用类型
# Object
显性创建new Object(),字面量创建{},属性key 是数值会被自动转换为字符串。
# Array
JS数组中每个槽位可以存储任意类型的数据。Array 构造函数还有两个ES6 新增的用于创建数组的静态方法:from()和of()。
form() 用于将类数组结构转换为数组实例
Array.form( )的第一个参数是一个类数组对象,或者有一个length 属性和可索引元素的结构
// 字符串会被拆分为单字符数组 console.log(Array.from("Matt")); // ["M", "a", "t", "t"] // 可以使用from()将集合和映射转换为一个新数组 const m = new Map().set(1, 2).set(3, 4); const s = new Set().add(1).add(2).add(3).add(4); console.log(Array.from(m)); // [[1, 2], [3, 4]] console.log(Array.from(s)); // [1, 2, 3, 4] // Array.from()对现有数组执行浅复制 const a1 = [1, 2, 3, 4]; const a2 = Array.from(a1); console.log(a1); // [1, 2, 3, 4] alert(a1 === a2); // false // 可以使用任何可迭代对象 const iter = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; yield 4; } }; console.log(Array.from(iter)); // [1, 2, 3, 4] // arguments 对象可以被轻松地转换为数组 function getArgsArray() { return Array.from(arguments); } console.log(getArgsArray(1, 2, 3, 4)); // [1, 2, 3, 4] // from()也能转换带有必要属性的自定义对象 const arrayLikeObject = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 }; console.log(Array.from(arrayLikeObject)); // [1, 2, 3, 4]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41第二个参数可传入映射函数参数,不再需要通过
Array.from().map()增强数组;第三个参数还可传入对象用于映射this值;如const a1 = [1, 2, 3, 4]; const a2 = Array.from(a1, x => x**2); const a3 = Array.from(a1, function(x) {return x**this.exponent}, {exponent: 2}); console.log(a2); // [1, 4, 9, 16] console.log(a3); // [1, 4, 9, 16]1
2
3
4
5of() 可以把一组参数转换为数组。可用来替代
Array.prototype.slice.call(arguments))
# 迭代器方法
ES6 中新增了3个用于检索数组内容的方法:keys()、values() 和 entries()
- keys() 返回数组索引的迭代器
- values() 返回数组元素的迭代器
- entries() 返回索引/值对的迭代器
const a = ["foo", "bar", "baz", "qux"];
// 因为这些方法都返回迭代器,可以使用 from方法或者 ...操作符转换
Array.from(a.keys()); // [0, 1, 2, 3]
Array.from(a.values()); // ["foo", "bar", "baz", "qux"]
Array.from(a.entries()); // [[0, "foo"], [1, "bar"], [2, "baz"], [3, "qux"]]
2
3
4
5
使用ES6 的解构可以非常容易地在循环中拆分键/值对:
const a = ["foo", "bar"];
for (const [idx, element] of a.entries()) {
alert(idx);
alert(element);
}
// 0
// foo
// 1
// bar
2
3
4
5
6
7
8
9
# 复制和填充方法
ES6 新增了两个方法:批量复制方法copyWithin(),以及填充数组方法fill()。使用这个方法不会改变数组的大小
const zeroes = [0, 0, 0, 0, 0];
// 用5 填充整个数组
zeroes.fill(5);
console.log(zeroes); // [5, 5, 5, 5, 5]
zeroes.fill(0); // 重置
2
3
4
5
# 转换方法
所有对象都有toLocaleString()、toString()和valueOf()方法。valueOf() 返回数组,toString() 返回逗号分割字符串
let colors = ["red", "blue", "green"];
colors.valueOf(); // ["red", "blue", "green"]
colors.toString(); // "red,blue,green"
2
3
如果想使用不同的分隔符,则可以使用join()方法
let colors = ["red", "green", "blue"];
alert(colors.join(",")); // red,green,blue
alert(colors.join("||")); // red||green||blue
2
3
如果传入 undefined 则依然为逗号分隔符
# 栈方法
ECMAScript 数组提供了push()和pop()方法,以实现类似栈的行为(后进先出); push 和 pop 都有返回值;push 和 pop 都有返回值;
- push 推入值,改变原始数组,增加数组的length 值,返回数组的最新长度
- pop 删除最后一位,改变原始数组,减少数组的length 值,返回被删除的项
# 队列方法
使用 shift()和 push(),队列以先进先出;shift() 它会删除数 组的第一项并返回它,然后数组长度减 1
const arr = [1, 2, 3, 4];
const item = arr.shift(); // 1
2
unshift() 从头部插入数据,与push刚好相反;使用 unshift () + pop () 或者 push() + shift() 可以实现一个队列只是方向相反
# 排序方法
有两个方法可以用来对元素重新排序:reverse()和 sort()
Reverse () 数组方向排序
Sort() 数组正向排序;sort会将数组每一项转换为字符串类型,即使时数值,然后比较字符串来决定顺序,然后比较字符串来决定顺序,然后比较字符串来决定顺序
let values = [0, 1, 5, 10, 15]; values.sort(); alert(values); // 0,1,10,15,51
2
3因为 即使数值5小于10,但二者的字符串排序却是相反的,由此可见默认的排序机制大多数情况下都是不适用的。 所以
sort支持传入一个比较函数用于判断哪个值应该排在前面。比较函数
比较函数接收两个参数,如果第一个参数应该排在第二个参数前面,就返回负值;如果两个参数相 等,就返回 0;如果第一个参数应该排在第二个参数后面,就返回正值。下面是使用简单比较函数的一 个例子:
function compare(value1, value2) { if (value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } } let values = [0, 1, 5, 10, 15]; values.sort(compare); alert(values); // [0, 1, 5, 10, 15]1
2
3
4
5
6
7
8
9
10
11
12也可以使用箭头函数 + 三元表达式
let values = [0, 1, 5, 10, 15]; values.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); alert(values); // [0, 1, 5, 10, 15]1
2
3如果比较的值都是数值还可以巧妙的用减法实现,如:
let values = [0, 1, 5, 10, 15]; values.sort((a, b) => a - b);1
2
# 操作方法
concat()方法可以再原数组的末尾追加新元素,返回一个新数组,不会改变原数组。不传值可做浅拷贝用let arr1 = [1,2,3]; let arr2 = arr1.concat([4,5,6]); // [1,2,3,4,5,6]1
2slice()用于截取原数组返回新数组,不改变原数组。可传入两个参数,为开始索引和结束索引。如果只传一个参数,则默认截取至数组末尾。let arr1 = [1,2,3,4]; let arr2 = arr1.slice(1, 3);// [2, 3]1
2splice() 主要目的是 在数组中间插入元素,但有 3 种不同的方式使用这个方法。
- 删除: 传入2个参数,第一个 开始位置索引, 第二个 删除的个数 。
splice(0, 2)会删除前两个元素 - 插入: 传入3个参数, 第一个 开始位置索引, 第二个 删除的个数,最后传入要插入的元素;比如,splice(2, 0, "red", "green")会从数组位置 2 开始插入字符串 "red"和"green"
- 替换: 传入3个参数,开始位 置、要删除元素的数量和要插入的任意多个元素。要插入的元素数量不一定跟删除的元素数量 一致。比如,splice(2, 1, "red", "green")会在位置 2 删除一个元素,然后从该位置开始 7 向数组中插入"red"和"green"。
- 删除: 传入2个参数,第一个 开始位置索引, 第二个 删除的个数 。
# 搜索和位置方法
ECMAScript 提供两类搜索数组的方法:按严格相等搜索和按断言函数搜索。
严格相等搜索
ECMAScript 提供了 3 个严格相等的搜索方法:
indexOf()、lastIndexOf()和includes();两项必须严格相等.indexOf()和lastIndexOf()都返回要查找的元素在数组中的位置,如果没找到则返回-1includes()返回布尔值
断言函数搜索
find()和findIndex()方法使用了断言函数- find()返回 第一个匹配的元素
- findIndex()返回第一个匹配元素的索引
const people = [ { name: "Matt", age: 27 }, { name: "Nicholas", age: 29 } ]; people.find((element, index, array) => element.age < 28); // {name: "Matt", age: 27} people.findIndex((element, index, array) => element.age < 28)); // 01
2
3
4
5
6
7
8
9
10
# 迭代方法
ECMAScript 为数组定义了 5 个迭代方法;传入两个参数,第一个为运行函数,第二个可选用来绑定this。
every(): 如果对每一项函数都返回 true,则这个方法返回 true。(全真)some(): 对数组每一项都运行传入的函数,如果有一项函数返回 true,则这个方法返回 true。(一真即真)
let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let everyResult = numbers.every((item, index, array) => item > 2);
console.log(everyResult); // false
let someResult = numbers.some((item, index, array) => item > 2);
console.log(someResult); // true
2
3
4
5
filter(): 函数返回 true 的项会组成数组之后返回。(返回符合条件的新数组 无符合返回空数组)
let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let filterResult = numbers.filter((item, index, array) => item > 2);
console.log(filterResult); // 3,4,5,4,3
2
3
forEach(): 对数组每一项都运行传入的函数,没有返回值。(改变原数组)
let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
numbers.forEach((item, index, array) => {
item * 3
});
console.log(numbers); // [1,2,3,4,5,4,3,2,1]
2
3
4
5
map(): 对数组每一项都运行传入的函数,返回由每次函数调用return的结果组成新数组。
let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let mapResult = numbers.map((item, index, array) => item * 2);
console.log(mapResult); // 2,4,6,8,10,8,6,4,2
2
3
# 归并方法
ECMAScript 为数组提供了两个归并方法:reduce()和 reduceRight();前者从前往后遍历,后者从后往前遍历。传给 reduce()和 reduceRight()的函数接收 4 个参数:上一个归并值(即上一次的值)、当前项、当前项的索引和数组本身
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur);
alert(sum); // 15
2
3