JS Object 方法大全
学习 Object.keys/values/entries/assign/freeze · 难度:进阶 · +15XP
JavaScript Object 静态方法大全
Object 静态方法是 JavaScript 内置 Object 构造函数上的一系列工具方法,用于对象的创建、属性控制、复制、合并、冻结、比较等操作。掌握这些方法是编写高质量 JavaScript 代码的基础,尤其在处理复杂对象操作时不可或缺。
对象复制与合并
| 方法 | 说明 | 注意 |
|---|---|---|
Object.assign(target, ...src) | 浅拷贝源对象属性到目标 | 修改 target,返回 target |
{ ...spread } | 扩展运算符浅拷贝 | 推荐,更简洁 |
structuredClone(obj) | 深拷贝(新 API) | 支持循环引用 |
// Object.assign 浅拷贝
const target = { a: 1 };
const src = { b: 2, c: 3 };
Object.assign(target, src);
console.log(target); // { a: 1, b: 2, c: 3 }
// 用于创建新对象(不修改原对象)
const merged = Object.assign({}, target, { d: 4 });
// 扩展运算符(推荐)
const merged2 = { ...target, d: 4 };
// 注意:assign 和 spread 都是浅拷贝
const nested = { arr: [1, 2], obj: { x: 1 } };
const copy = { ...nested };
copy.arr.push(3); // 会影响原对象!
copy.obj.x = 2; // 会影响原对象!
// 解决:使用 structuredClone 或 JSON 序列化
const deep = structuredClone(nested);
对象属性控制方法
Object.defineProperty(obj, prop, descriptor)定义单个属性Object.defineProperties(obj, descriptors)定义多个属性Object.getOwnPropertyDescriptor(obj, prop)获取属性描述符
const user = {};
// 定义带 getter/setter 的属性
Object.defineProperty(user, "fullName", {
get() {
return this.firstName + " " + this.lastName;
},
set(value) {
[this.firstName, this.lastName] = value.split(" ");
},
enumerable: true,
configurable: true
});
user.fullName = "三 张";
console.log(user.firstName); // "三"
console.log(user.fullName); // "三 张"
// 获取属性描述符
const desc = Object.getOwnPropertyDescriptor(user, "fullName");
console.log(desc.get); // [Function: get]
console.log(desc.set); // [Function: set]
对象限制方法(不可变性)
| 方法 | 禁止添加属性 | 禁止修改属性 | 禁止删除属性 | 级别 |
|---|---|---|---|---|
Object.preventExtensions() | 是 | 否 | 否 | 轻 |
Object.seal() | 是 | 否(可修改现有) | 是 | 中 |
Object.freeze() | 是 | 是 | 是 | 重 |
const obj = { x: 1, y: 2 };
// freeze: 完全冻结(浅冻结)
Object.freeze(obj);
// obj.x = 10; // 静默失败(严格模式会报错)
// obj.z = 3; // 静默失败
// delete obj.x; // 静默失败
console.log(obj.x); // 1(未改变)
// 检查对象状态
console.log(Object.isFrozen(obj)); // true
console.log(Object.isSealed(obj)); // true(frozen 包含 sealed)
console.log(Object.isExtensible(obj)); // false
// 深冻结函数
function deepFreeze(obj) {
Object.freeze(obj);
Object.getOwnPropertyNames(obj).forEach(prop => {
if (obj[prop] !== null && typeof obj[prop] === "object" && !Object.isFrozen(obj[prop])) {
deepFreeze(obj[prop]);
}
});
return obj;
}
其他实用方法
// Object.fromEntries(): 从键值对数组创建对象
const entries = [["name", "张三"], ["age", 25], ["city", "北京"]];
const obj = Object.fromEntries(entries);
console.log(obj); // { name: "张三", age: 25, city: "北京" }
// 与 Map 互相转换
const map = new Map(entries);
const objFromMap = Object.fromEntries(map);
// Object.entries(): 对象转数组(常用于遍历)
const person = { name: "张三", age: 25 };
for (const [key, value] of Object.entries(person)) {
console.log(key + ": " + value);
}
// Object.hasOwn(): 安全的自有属性检查(ES2022,替代 hasOwnProperty)
console.log(Object.hasOwn(person, "name")); // true
console.log(Object.hasOwn(person, "toString")); // false
// Object.groupBy(): 分组(ES2024)
const users = [{ name: "A", age: 20 }, { name: "B", age: 30 }, { name: "C", age: 20 }];
const grouped = Object.groupBy(users, u => u.age);
console.log(grouped); // { "20": [{...},{...}], "30": [{...}] }