前端学习第十六天——进一步走近ES6
剩余参数
…args是剩余参数
const add = (x, y, z, ...args) => {};
剩余参数永远是个数组,即使没有值,也是空数组。
注意事项
- 箭头函数的剩余参数
箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号 - 使用剩余参数替代 arguments 获取实际参数
const add = function () {
console.log(arguments);
};
const add = (...args) => {
console.log(args);
};
- 剩余参数的位置
剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错
数组的展开运算符
在数组前面加上…即可展开数组
剩余参数和展开运算符的区别
- 根本区别
展开运算符,数组转换成参数列表
[3,1,2]->3,1,2
剩余参数,参数列表转换成数组
3,1,2->[3,1,2]
- 区分剩余参数和展开运算符
// 剩余参数
const add = (...args) => {
console.log(args);
// 展开运算符
console.log(...args);
console.log([...[1, 2, 3], 4]); // [1, 2, 3, 4]
对象的展开运算符
对象不能直接展开,必须在 {} 中展开
const apple = {
color: '红色',
shape: '球形',
taste: '甜'
};
console.log({ ...apple });
console.log({ ...apple } === apple); // false
对象的展开:把属性罗列出来,用逗号分隔,放到一个 {} 中,构成新对象
对象的合并
新对象拥有全部属性,相同属性,后者覆盖前者
console.log({ ...obj1, ...obj2 });
注意事项
- 空对象的展开
如果展开一个空对象,则没有任何效果 - 非对象的展开
如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来
如果展开运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象 - 对象中对象属性的展开
不会展开对象中的对象属性
Set
和Map
Set
ES6 提供了新的数据结构Set
。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set
本身是一个构造函数,用来生成 Set
数据结构。
const s = new Set();
Set
没有下标去标示每一个值,所以 Set
是无序的,也不能像数组那样通过下标去访问 Set
的成员
Set
的方法和属性
add()
方法
向Set
中添加成员,一次只能添加一个成员。若添加的新成员已经存在,则不再添加。
const s = new Set();
s.add(1).add(2).add(2);
has()
方法
判断Set
中是否含有指定成员,存在返回true,不存在返回false。
s.has(1);
delete()
方法
使用 delete
删除不存在的成员,什么都不会发生,也不会报错
s.delete(1);
clear()
方法
清空Set
s.clear();
forEach()
方法
按照成员添加进集合的顺序遍历
s.forEach(function (value, key, set) {
// Set中value和key是相等的
// set指代前面的s
console.log(value, key, set === s);
console.log(this); // #document
}, document);
// documnet,用来修改修改this指向
size
属性
相当于数组的长度,可以返回Set
中成员的个数。
console.log(s.size);
Set
构造函数的参数
- 数组
- 字符串、arguments、NodeList、Set 等
// arguments
function func() {
console.log(new Set(arguments));
}
func(1, 2, 1);
// Set,相当于复制一个Set
const s = new Set([1, 2, 1]);
console.log(new Set(s) === s); // false
Set
的注意事项
- 判断重复的方式
Set
对重复值的判断基本遵循严格相等(=)
但是对于 NaN 的判断与 === 不同,NaN=NaN结果是false,Set
中 NaN 等于 NaN - 什么时候使用
Set
- 数组或字符串去重时
- 不需要通过下标访问,只需要遍历时
- 为了使用
Set
提供的方法和属性时(add delete clear has forEach size 等)
Map
ES6提供了Map
数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
// 对象
const person = {
name: 'zgbx',
age: 18
};
// Map
const m = new Map();
m.set('name', 'zgbx');
m.set('age', 18);
Map 和对象的区别
对象一般用字符串当作键
Map
中基本数据类型:数字、字符串、布尔值、undefined、null。引用数据类型:对象([]、{}、函数、Set、Map 等)都可以作为 Map
的键
Map
的方法和属性
set()
方法
使用 set 添加的新成员,键如果已经存在,后添加的键值对覆盖已有的
const m = new Map();
m.set('age', 18).set(true, 'true').set('age', 20);
-
get()
方法
get()
方法可以通过键去寻找值
get 获取不存在的成员,返回 undefined -
has()
方法
判断键是否存在 -
delete()
方法
delete方法可以删除指定的键值对,使用 delete 删除不存在的成员,什么都不会发生,也不会报错 -
clear()
方法
删除所有的键值对,清空Map
-
forEach()
方法
m.forEach(function (value, key, map) {
console.log(value, key, map === m);
console.log(this);
}, document);
- size
可以返回Map
中键值对的个数
Map
构造函数的参数
- 数组
只能传二维数组,而且必须体现出键和值
console.log(
new Map([
['name', 'alex'],
['age', 18]
])
);
- Set、Map 等
// Set
// Set 中也必须体现出键和值
const s = new Set([
['name', 'zgbx'],
['age', 18]
]);
console.log(new Map(s));
console.log(s);
// Map
// 复制了一个新的 Map
const m1 = new Map([
['name', 'zgbx'],
['age', 18]
]);
const m2 = new Map(m1);
console.log(m2, m2 === m1); //false
Map
的注意事项
- 判断键名是否相同的方式
基本遵循严格相等(===)
例外就是 NaN,Map
中 NaN 也是等于 NaN - 什么时候使用
Map
- 如果只是需要 key -> value 的结构,或者需要字符串以外的值做键,使用 Map 更合适
- 只有模拟现实世界的实体时,才使用对象
Iterator
遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator
接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
const it = [1, 2][Symbol.iterator]();
console.log(it.next()); // {value: 1, done: false}
console.log(it.next()); // {value: 2, done: false}
console.log(it.next()); // {value: undefined, done: true}
it:可遍历对象(可迭代对象)
Symbol.iterator:可遍历对象的生成方法。
Symbol.iterator(可遍历对象的生成方法) -> it(可遍历对象) -> it.next() -> it.next() -> …(直到 done 为 true)
for…of
for (const item of arr) {
console.log(item);
}
for…of 循环只会遍历出那些 done 为 false 时,对应的 value 值
- 与 break、continue 一起使用
const arr = [1, 2, 3];
for (const item of arr) {
if (item === 2) {
// break;
continue;
}
console.log(item);
}
- 在 for…of 中
keys()
方法得到的是索引的可遍历对象,可以遍历出索引值
values()
方法得到的是值的可遍历对象,可以遍历出值
entries()
方法得到的是索引+值组成的数组的可遍历对象
原生可遍历
数组、字符串、Set、Map、arguments、NodeList
非原生可遍历
一般的对象
const person = { sex: 'male', age: 18 };
person[Symbol.iterator] = () => {
let index = 0;
return {
next() {
index++;
if (index === 1) {
return {
value: person.age,
done: false
};
} else if (index === 2) {
return {
value: person.sex,
done: false
};
} else {
return {
done: true
};
}
}
};
};
有 length 和索引属性的对象
const obj = {
'0': 'alex',
'1': 'male',
length: 2
};
obj[Symbol.iterator] = () => {
let index = 0;
return {
next() {
let value, done;
if (index < obj.length) {
value = obj[index];
done = false;
} else {
value = undefined;
done = true;
}
index++;
return {
value,
done
};
}
};
};
字符串的新增方法
includes()
方法
判断字符串中是否含有某些字符
`abc'.includes('a');
第二个参数表示开始搜索的位置,默认是0
`abc'.includes('a', 0);
padStart()
方法和padEnd()
padStart()
方法用于从头部补全字符串长度
padEnd()
方法用于从尾部补全字符串长度
console.log('x'.padStart(5, 'ab')); // ababx
console.log('x'.padEnd(5, 'ab')); // xabab
console.log('x'.padEnd(4, 'ab')); // xaba
原字符串的长度,等于或大于最大长度,不会消减原字符串,字符串补全不生效,返回原字符串。
用来补全的字符串与原字符串长度之和超过了最大长度,截去超出位数的补全字符串,原字符串不动。
如果省略第二个参数,默认使用空格补全长度。
3. trimStart()
和trimEnd()
清除字符串的首或尾空格,中间的空格不会清除
const s = ' a b c ';
// 清除头部空格
s.trimStart();
s.trimLeft();
// 清除尾部空格
s.trimEnd();
s.trimRight();
// 清除全部空格,中间的空格不会清除
s.trim();
数组的新增方法
includes()
方法- 判断数组中是否含有某个成员。
- 第二个参数表示搜索的起始位置,默认值是 0
- 基本遵循严格相等(===),但是对于 NaN 的判断与 === 不同,includes 认为 NaN === NaN
Array.from()
方法
将其他数据类型转换成数组
Array.from('str')
所有可遍历的,如数组、字符串、Set、Map、NodeList、arguments等,拥有 length 属性的任意对象。都可以通过Array.from()
方法转换成数组
Array.from()
方法的第二个参数,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from()
方法的第三个参数。
Array.from(
'12',
value => {
console.log(this);
},
document
);
find()
方法和findIndex()
方法
find()
方法找到满足条件的一个立即返回。
findIndex()
方法找到满足条件的一个,立即返回其索引。
对象的新增方法
Object.assign()
方法
用来合并对象,直接合并到了第一个参数中,返回的就是合并后的对象。还可以合并多个对象。
- 基本数据类型作为源对象,与对象的展开类似,先转换成对象,再合并
- 同名属性的替换后面的直接覆盖前面的
Object.keys()
方法
获取对象键值Object.values()
方法
获取对象的值Object.entries()
方法
获取对象的键和值
Object.keys()
、values()
、entires()
并不能保证顺序一定是你看到的样子,这一点和 for in 是一样的。