🌐ES6 这 8 个隐藏外挂,知道 3 个算我输!

标签:ES6、JavaScript、性能优化、代码简化


"代码写得少,Bug 自然少。"------鲁迅(并没有说)

今天不聊 React、不聊 Vue,回到语言层,挖一挖那些"官方早就给了,但我们总自己造轮子"的 ES6 冷门 API。

它们每一个都经过浏览器真·原生实现,无 polyfill 也能跑一句顶五句,看完直接复制粘贴就能让同事惊呼"还有这种操作?"。


1. 数组拍平:flat / flatMap

场景:后端把树形结构一股脑塞给你,前端只想拿叶子节点。

js 复制代码
// 商品按类目嵌套:[[手机,耳机],[笔记本,鼠标]]
const goods = [['iPhone','AirPods'],['MacBook','MagicMouse']];

// 旧写法
const all = goods.reduce((a, b) => a.concat(b), []); 

// 新写法
const all = goods.flat();          // 默认 1 层
const deep = goods.flat(Infinity); // 无限层

bonusflatMap = map + flat(1),一次循环搞定"一对多"映射。

js 复制代码
const users = [{name:'张三',tags:'前端,TS'},{name:'李四',tags:'后端,Go'}];
const pairs = users.flatMap(u => u.tags.split(',').map(t => ({name:u.name, tag:t})));
// [{name:'张三',tag:'前端'}, {name:'张三',tag:'TS'}, ...]

2. 对象 ↔ 数组"瞬移":entries ↔ fromEntries

场景 :只想给对象做"过滤 / 映射 / 排序",又懒得写 reduce

js 复制代码
const score = { 语文:95, 数学:82, 英语:76 };

// 保留 >80 的学科
const pass = Object.fromEntries(
  Object.entries(score).filter(([k,v]) => v > 80)
);
// { 语文:95, 数学:82 }

URL 解析也能一行完成:

js 复制代码
const params = Object.fromEntries(new URLSearchParams('name=张三&age=25'));
// { name:'张三', age:'25' }

3. 字符串补全:padStart / padEnd

场景:时间、订单、身份证,位数必须对齐。

js 复制代码
const now = new Date();
const time = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}`;
// "09:05" 而不是 "9:5"

固定编号

js 复制代码
const orderId = '457';
const fullId = orderId.padStart(8, '0'); // "00000457"

4. 数组去重 + 集合运算:Set

场景:接口返回了 1w 条数据,里面重复 ID 占 30%。

js 复制代码
const ids = [3,5,5,7,3,9];
const unique = [...new Set(ids)];        // [3,5,7,9]

// 交集 / 差集,同样一行
const a = new Set([1,2,3]);
const b = new Set([3,4,5]);
const intersect = [...a].filter(v => b.has(v)); // [3]
const diff      = [...a].filter(v => !b.has(v)); // [1,2]

5. 解构"嵌套 + 默认值"

场景:接口字段经常缺失,还要做降级。

js 复制代码
function ajax({
  url,
  method = 'GET',          // 默认值
  timeout = 5000,
  headers: { token = '' } = {}  // 嵌套默认值
} = {}) {
  console.log(url, method, token);
}

深层安全取值

js 复制代码
const { address: { city, detail = '暂无' } = {} } = user;
// 无论 user.address 是否存在都不会报错

6. 真正"私有"属性:Symbol

场景:写工具库,怕用户覆盖你的内部字段。

js 复制代码
const _secret = Symbol('secret');
class Cache {
  [_secret] = new Map();
  set(k,v){ this[_secret].set(k,v); }
  get(k){ return this[_secret].get(k); }
}
const c = new Cache();
c['secret'] = 123;        // 不影响内部
console.log(c[_secret]);  // 外部拿不到

还能改 toString 标签

js 复制代码
class Queue {
  [Symbol.toStringTag] = 'Queue';
}
`${new Queue}`; // "[object Queue]"

7. 对象操作"统一入口":Reflect

场景:写 Proxy 拦截,总担心"死循环"。

js 复制代码
const proxy = new Proxy(target, {
  get(t, k){
    console.log('read', k);
    return Reflect.get(t, k); // 调用原始行为,安全
  }
});

安全删除

js 复制代码
const ok = Reflect.deleteProperty(obj, 'a'); // 返回布尔,可判断

8. 异步"扫尾"神器:finally()

场景:请求结束必须关 loading,成功失败都得关。

js 复制代码
function load(){
  showLoading();
  return fetch('/api/data')
    .then(render)
    .catch(showError)
    .finally(hideLoading); // 只写一次
}

结语:如何无痛养成"新习惯"?

  1. 代码评审刻意问一句 :这里能用 flatMap / fromEntries 吗?
  2. 立 Flag:连续三周在业务里用满这 8 个 API,每用一次给自己打 ★。
  3. 团队分享:把本文甩到群里,谁最晚在 PR 里用到,请全组奶茶 🧋。

"轮子"官方已经造好,下次再手写 reduce 去重,就罚自己抄十遍 flat(Infinity) 吧!

相关推荐
汤姆Tom1 小时前
Node.js 版本管理、NPM 命令、与 NVM 完全指南
前端·npm·node.js
东坡白菜1 小时前
SSE 实现 AI 对话中的流式输出
javascript·vue.js
Alan521591 小时前
Java 后端实现基于 JWT 的用户认证和权限校验(含代码讲解)
前端·后端
RoyLin2 小时前
TypeScript设计模式:策略模式
前端·后端·typescript
brzhang2 小时前
为什么说低代码谎言的破灭,是AI原生开发的起点?
前端·后端·架构
甜瓜看代码2 小时前
Android事件分发机制
面试
小桥风满袖3 小时前
极简三分钟ES6 - ES9中字符串扩展
前端·javascript
小Wang3 小时前
npm私有库创建(docker+verdaccio)
前端·docker·npm
用户73087011793083 小时前
Vue中集成文字转语音:使用Web Speech API实现功能
前端