数组与对象
对象进阶
掌握 Object.keys/values/entries、属性描述符
对象进阶
深入理解 JavaScript 对象的特性与方法。
学完本章你将: 掌握属性描述符、合并复制、冻结密封。
对象合并与复制
javascript
// Object.assign 浅拷贝
let target = { a: 1 };
let source = { b: 2, c: 3 };
Object.assign(target, source);
console.log(target); // { a: 1, b: 2, c: 3 }
// 浅拷贝到空对象
let obj = { x: 1, y: { z: 2 } };
let copy = Object.assign({}, obj);
copy.y.z = 99;
console.log(obj.y.z); // 99(嵌套对象被共享!)
// 展开运算符(推荐)
let clone = { ...obj, extra: "new" };
console.log(clone); // { x: 1, y: { z: 99 }, extra: "new" }
深拷贝
javascript
let original = {
name: "Alice",
scores: [90, 85],
address: { city: "北京" },
};
// JSON 方式(有限制)
let deep1 = JSON.parse(JSON.stringify(original));
deep1.address.city = "上海";
console.log(original.address.city); // "北京"(未影响)
// ⚠️ JSON 不能处理:函数、undefined、Symbol、循环引用
// structuredClone(现代推荐)
let deep2 = structuredClone(original);
deep2.scores.push(100);
console.log(original.scores); // [90, 85](未影响)
属性描述符
javascript
let user = {};
Object.defineProperty(user, "name", {
value: "Alice",
writable: false, // 不能修改
enumerable: true, // 可被枚举
configurable: false, // 不能删除/重新定义
});
user.name = "Bob"; // 静默失败(严格模式报错)
console.log(user.name); // "Alice"
// 获取描述符
let desc = Object.getOwnPropertyDescriptor(user, "name");
console.log(desc); // { value: "Alice", writable: false, ... }
冻结与密封
javascript
let obj = { x: 1, y: 2 };
// Object.freeze:完全不可变
let frozen = Object.freeze({ a: 1, nested: { b: 2 } });
// frozen.a = 10; // ❌ 静默失败
frozen.nested.b = 20; // ✅ 浅冻结,嵌套对象仍可修改!
console.log(Object.isFrozen(frozen)); // true
// Object.seal:不能增删属性,但可修改
let sealed = Object.seal({ a: 1 });
sealed.a = 10; // ✅ 可以修改
// sealed.b = 20; // ❌ 不能新增
// delete sealed.a; // ❌ 不能删除
console.log(Object.isSealed(sealed)); // true