🧑💻 寫在開頭
點贊 + 收藏 === 學會🤣🤣🤣
“代碼寫得少,Bug 自然少。”——魯迅(並沒有説)
今天不聊 React、不聊 Vue,回到語言層,挖一挖那些“官方早就給了,但我們總自己造輪子”的 ES6 冷門 API。
它們每一個都經過瀏覽器真·原生實現,無 polyfill 也能跑,一句頂五句,看完直接複製粘貼就能讓同事驚呼“還有這種操作?”。
1. 數組拍平:flat / flatMap
場景:後端把樹形結構一股腦塞給你,前端只想拿葉子節點。
// 商品按類目嵌套:[[手機,耳機],[筆記本,鼠標]] 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); // 無限層
flatMap = map + flat(1),一次循環搞定“一對多”映射。
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。
const score = { 語文:95, 數學:82, 英語:76 };
// 保留 >80 的學科
const pass = Object.fromEntries(
Object.entries(score).filter(([k,v]) => v > 80)
);
// { 語文:95, 數學:82 }
URL 解析也能一行完成:
const params = Object.fromEntries(new URLSearchParams('name=張三&age=25'));
// { name:'張三', age:'25' }
3. 字符串補全:padStart / padEnd
場景:時間、訂單、身份證,位數必須對齊。
const now = new Date();
const time = `${now.getHours().toString().padStart(2,'0')}:${now.getMinutes().toString().padStart(2,'0')}`;
// "09:05" 而不是 "9:5"
固定編號:
const orderId = '457'; const fullId = orderId.padStart(8, '0'); // "00000457"
4. 數組去重 + 集合運算:Set
場景:接口返回了 1w 條數據,裏面重複 ID 佔 30%。
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. 解構“嵌套 + 默認值”
場景:接口字段經常缺失,還要做降級。
function ajax({
url,
method = 'GET', // 默認值
timeout = 5000,
headers: { token = '' } = {} // 嵌套默認值
} = {}) {
console.log(url, method, token);
}
深層安全取值:
const { address: { city, detail = '暫無' } = {} } = user;
// 無論 user.address 是否存在都不會報錯
6. 真正“私有”屬性:Symbol
場景:寫工具庫,怕用户覆蓋你的內部字段。
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 標籤:
class Queue {
[Symbol.toStringTag] = 'Queue';
}
`${new Queue}`; // "[object Queue]"
7. 對象操作“統一入口”:Reflect
場景:寫 Proxy 攔截,總擔心“死循環”。
const proxy = new Proxy(target, {
get(t, k){
console.log('read', k);
return Reflect.get(t, k); // 調用原始行為,安全
}
});
const ok = Reflect.deleteProperty(obj, 'a'); // 返回布爾,可判斷
8. 異步“掃尾”神器:finally()
場景:請求結束必須關 loading,成功失敗都得關。
function load(){
showLoading();
return fetch('/api/data')
.then(render)
.catch(showError)
.finally(hideLoading); // 只寫一次
}