JS基础篇-ES6+新增API

138 阅读3分钟

1. Map 比 Object 为什么更好?

    1. Key 类型更灵活
    1. 更直观的内置方法
    1. 处理大型数据性能更好
    1. 保留插入顺序
    1. 避免原型污染

Key 类型更灵活

Object: 对象键 只能是字符串或符号。其他类型(例如对象、函数和数字)会 自动转换为字符串:

const obj = {}; 
const key = { a1 }; 
obj[key] = '2'console.log(obj);    // { "[object Object]": "2" }

Map: Map 的键可以是 任何类型,包括对象、函数和 NaN:

const map = new Map(); 
const key = { a1 }; 
map.set(key, '2'); 
console.log(map.get(key)); // "2"

更直观的内置方法

Object:

obj[key] = value;      // 添加属性
obj[key];              // 获取属性的值
delete obj[key];       // 删除属性 
Object.keys(obj).length// 获取属性的数量

Object.keys(obj).forEach(key => { /* ... */ });  
Object.values(obj).forEach(value => { /* ... */ });  
Object.entries(obj).forEach(([key, value]) => { /* ... */ });

Map:

map.set(key, value);  // 添加属性  
map.get(key);         // 获取属性的值  
map.has(key);         // 属性是否存在  
map.delete(key);      // 删除属性  
map.clear();          // 删除所有属性   
map.size;             // 获取属性的数量

map.forEach((value, key) => { /* ... */ });  
for (const [key, value] of map) { /* ... */ }

处理大型数据性能更好

  • 频繁的增删改查操作:Map 针对频繁的键值插入和删除操作做了优化。
  • 处理大型数据集:Map 通常在内存使用和访问速度方面表现更好,尤其是动态生成的键。

保留插入顺序

Map 严格维护键值对的插入顺序,非常适合顺序很重要的场景:

const map = new Map();  
map.set('a'1);  
map.set('b'2);  
console.log([...map]); // [['a', 1], ['b', 2]]

避免原型污染

Object容易受到原型链污染:

Copyconst obj = {}; 
console.log(obj.constructor); 
obj.hasOwnProperty('key'); 

Map 独立于原型链:

const map = new Map(); 
console.log(map.constructor); 
map.set('hasOwnProperty''safe');

2. 数据处理的隐藏利器 Set

数组在处理唯一性和查找效率方面存在明显短板,Set的引入正是为了解决这些问题:

  • 重复值问题: 数组允许存储重复值,导致唯一性检查需要额外的逻辑。
  • 低效的存在性检查: 查找数组中是否存在某个元素需要线性搜索(如Array.includes),时间复杂度为O(n),对于大型数据集来说性能较差。

常见应用场景

  • 去重:快速去除数组中的重复值。
  • 存在性检查:高效判断某个值是否存在于集合中。
  • 数据集合操作:如并集、交集、差集等。

更直观的内置方法

const mySet = new Set();   
// 向Set中添加一个值(如果值已存在,则忽略)
mySet.add(1);   // 输出: Set(2) { 1, 2 }
// 从Set中删除指定的值
mySet.delete(1);  // 输出: Set(1) { 2 }
// 检查Set中是否存在某个值
console.log(mySet.has(2)); // 输出: true
// 返回Set中元素的数量
console.log(mySet.size); // 输出: 1
// 清空Set中的所有元素
mySet.clear();   console.log(mySet.size); // 输出: 0
// Set是可迭代的,可以通过for...of或forEach进行遍历

const mySet = newSet([123]);   
for (const value of mySet) {   
    console.log(value);   
}   
// 输出:  
// 1   
// 2   
// 3   

mySet.forEach(value =>console.log(value));   
// 输出:   
// 1   
// 2   
// 3

Set与数组的性能对比

1. 时间复杂度
  • Set在添加、删除和查找操作上的时间复杂度为O(1),
  • 而数组的这些操作通常需要O(n)。对于大型数据集,Set的性能优势尤为明显。
2. 适用场景
  • 使用Set:当需要快速查找、去重或频繁添加/删除元素时。
  • 使用数组:当需要按索引访问元素或维护元素顺序时。

3. 从回调函数到 async/await 的进化

Promise 链式调用(异步优化)

  • 扁平链式调用 → 避免嵌套
  • 集中错误处理 → .catch()
  • 但仍需频繁书写 .then()

async/await(“同步式” 异步)

“async/await 是 Generator 的语法糖,通过状态机和 Promise 实现‘异步转同步’:

  1. await 暂停函数,返回 Promise → 状态保存
  2. Promise 完成后恢复执行 → 事件循环调度
  3. 代码顺序与逻辑顺序一致,但本质仍为异步 → 非阻塞