文章目录
-
- [1. 引言](#1. 引言)
- [2. 正文](#2. 正文)
-
- [2.1 对象字面量的"三大增强"](#2.1 对象字面量的“三大增强”)
- [2.2 Object 静态方法锦囊与 ES2024 新特性](#2.2 Object 静态方法锦囊与 ES2024 新特性)
- [2.3 函数的"微调"与未来特性](#2.3 函数的“微调”与未来特性)
- [3. 常见问题 (FAQ)](#3. 常见问题 (FAQ))
- [4. 总结](#4. 总结)
1. 引言
在前几篇文章中,我们聊了解构赋值、展开运算符和 Class。但其实在日常开发中,我们打交道最多的还是普通的对象字面量 {} 和函数。
ES6 并没有止步于 let 和 const,它对对象和函数做了大量的"微整形"手术,比如属性简写、计算属性名等。而到了 ES2024,JavaScript 甚至有了原生的 groupBy 方法!
如果你还在用 ES5 的方式拼接 JSON 对象,或者手写 reduce 来做分组,那这篇绝对能让你"爽"到。
本文将带你掌握:
- 如何写出优雅的对象字面量(计算属性名、简写)。
- 如何用 ES2024 的
Object.groupBy一行代码搞定数据分组。 - 什么是函数尾逗号?为什么大家都爱用它?
- 前瞻:装饰器提案。
2. 正文
2.1 对象字面量的"三大增强"
在 ES5 时代,定义一个动态对象是很麻烦的。ES6 让对象字面量变得更强大、更像 JSON。
1. 属性简写
当对象的属性名和变量名相同时,可以直接简写。这在 Vue 组件 data() 或 Redux mapStateToProps 中非常常见。
javascript
const name = "Tom";
const age = 18;
// ES5: { name: name, age: age }
const user = { name, age };
console.log(user); // { name: "Tom", age: 18 }
2. 方法简写
定义方法时,可以省略 : function 关键字。
javascript
const app = {
// ES5: init: function() { ... }
init() {
console.log("App started!");
}
};
3. 计算属性名
这是一个神技!允许你在对象字面量里使用表达式 作为 Key。以前你只能在对象创建完后再用 obj[key] 赋值。
javascript
const key = "id";
const prefix = "user_";
// 动态生成 Key
const user = {
[prefix + key]: 1001, // user_id: 1001
["get" + "Name"]() { // 定义了 getName 方法
return "Jack";
}
};
console.log(user.user_id); // 1001
console.log(user.getName()); // "Jack"
2.2 Object 静态方法锦囊与 ES2024 新特性
Object 构造函数本身提供了很多实用的静态方法(不需要 new Object,直接用 Object.xxx)。
1. 对象遍历三剑客
Object.keys(obj):返回键数组。Object.values(obj):返回值数组。Object.entries(obj):返回[key, value]对数组(配合Map使用神器)。
javascript
const obj = { a: 1, b: 2 };
// 快速转 Map
const map = new Map(Object.entries(obj));
2. Object.fromEntries(ES2019)
这是 entries 的逆操作,把二维数组转回对象。常用于 URL 参数处理。
javascript
const params = new URLSearchParams("foo=1&bar=2");
// Object.fromEntries 把它转为普通对象 { foo: "1", bar: "2" }
const obj = Object.fromEntries(params);
3. Object.groupBy(ES2024 最新特性)
以前我们要根据某个属性(如年龄)对数组对象分组,必须手写复杂的 reduce。现在原生支持了!
注意:Node.js 需 v22+ 或开启 flag,Chrome 需要 v117+。
javascript
const products = [
{ name: "Apple", category: "Fruit" },
{ name: "Banana", category: "Fruit" },
{ name: "Carrot", category: "Vegetable" },
];
// 一行代码分组!
const grouped = Object.groupBy(products, ({ category }) => category);
console.log(grouped);
// {
// Fruit: [{ name: "Apple" ...}, { name: "Banana" ...}],
// Vegetable: [{ name: "Carrot" ...}]
// }

2.3 函数的"微调"与未来特性
1. 尾逗号
这是一个很多人忽视但极其实用的特性。允许在函数定义和调用时的最后一个参数后面加逗号。
javascript
function createUser(
name,
age, // 加个逗号
) { }
createUser(
"Jack",
18, // 加个逗号
);
好处 :当你重构代码,把 gender 加在 age 后面时,Git Diff 只会显示新增一行,而不会显示上一行 age 也变了(因为加了逗号)。这对于多人协作项目的 Git Review 非常友好!
2. 前瞻:装饰器
装饰器目前处于 Stage 3 阶段,是 JS 未来的明星特性(TypeScript 中已广泛使用)。它本质上是一个函数,用来修改类或类的属性。
javascript
// 这是一个装饰器工厂
function readonly(target, key, descriptor) {
descriptor.writable = false;
return descriptor;
}
class User {
constructor(name) { this.name = name; }
@readonly // 给方法加装饰器
getName() {
return this.name;
}
}
const u = new User("Tom");
u.getName = function() {}; // 报错!Cannot assign to read only property
虽然标准 JS 中还需要等待,但在 React 开发中,很多 MobX 状态管理的写法都是依赖装饰器语法的。
3. 常见问题 (FAQ)
Q1:Object.assign 和 {...obj} 有什么区别?
A:
- 效果上:都是浅拷贝(第一层)。
- 细节上:
Object.assign会触发对象的 setter,而展开运算符在某些旧版实现中可能不会。此外,Object.assign第一个参数会被修改(目标对象),而展开运算符总是产生新对象。通常推荐用展开运算符,更语义化。
Q2:Object.groupBy 现在可以在生产环境用了吗?
A: 取决于你的目标环境。如果你用最新的 Vite/Rollup 打包,或者主要在现代浏览器中运行,可以使用。如果需要兼容 IE 或旧版 Node,还是推荐使用 lodash 的 _.groupBy,或者自己手写 reduce。
Q3:装饰器只能用在 Class 上吗?
A: 在目前的提案中,装饰器主要应用在 Class(类)、Class 的属性(方法)、Accessor(getter/setter)上。暂不支持普通函数装饰。
4. 总结
JavaScript 的对象和函数语法正在变得越来越像主流的后端语言:
- 对象字面量增强:属性简写、方法简写、计算属性名,让定义配置对象极极极简单。
- Object 静态方法 :
entries/fromEntries实现了对象与数组的无损互转,groupBy省去了手写循环的烦恼。 - 尾逗号 :不仅能用,而且推荐用,对代码维护友好。
- 装饰器:虽然还在路上,但它是面向切面编程(AOP)在 JS 中的实现,值得了解。
最佳实践建议:
在构建大型配置对象时,充分利用计算属性名和属性简写。在处理对象数据流转换时,多看看
Object身上有没有现成的方法,别总想着写for循环。
下一篇预告 :JavaScript 不仅是脚本,它也涉及到底层类型。下一篇我们将深入探讨 BigInt、Symbol、正则增强以及 Intl 等标准库扩展。
如果觉得本文对你有帮助,请点赞👍、收藏⭐、关注👀,三连支持一下!
有问题欢迎在评论区留言:你最喜欢 ES6 对象字面量的哪个新特性?