🧑🏫 作者:全栈老李
📅 更新时间:2025 年 05 月
🧑💻 适合人群:前端初学者、进阶开发者
🚀 版权:本文由全栈老李原创,转载请注明出处。
大家好,我是全栈老李。今天咱们聊聊ES6中Object的那些新方法——它们就像瑞士军刀,让对象操作变得前所未有的顺手。想象一下,以前你要手动遍历对象属性时那笨拙的样子,现在有了这些方法,简直像开了挂。
一、Object.assign:对象的"复制粘贴"
Object.assign
是ES6中最常用的对象方法之一,它的作用就像把多个对象的属性"复制粘贴"到目标对象上。
// 全栈老李示例:Object.assign基础用法
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
const result = Object.assign(target, source1, source2);
console.log(result); // { a: 1, b: 2, c: 3 }
console.log(target); // { a: 1, b: 2, c: 3 } —— 注意target也被修改了!
这里有个坑要注意:Object.assign
会直接修改第一个参数对象本身!如果你想保留原对象,可以这样:
// 全栈老李提醒:安全的浅拷贝方式
const newObj = Object.assign({}, target, source1, source2);
使用场景:
- 合并配置对象(比如合并默认配置和用户自定义配置)
- 创建对象的浅拷贝
- 给对象添加多个属性
不过要注意,它只能做浅拷贝。如果属性值是对象,拷贝的是引用:
const obj = { a: { b: 1 } };
const copy = Object.assign({}, obj);
copy.a.b = 2;
console.log(obj.a.b); // 2 —— 原对象也被改了!
二、Object.keys/values/entries:对象的"解剖工具"
这三个方法让遍历对象变得异常简单,它们分别返回对象的键、值、键值对数组。
// 全栈老李示例:对象遍历三件套
const person = {
name: '老李',
age: 35,
job: '全栈工程师'
};
console.log(Object.keys(person)); // ["name", "age", "job"]
console.log(Object.values(person)); // ["老李", 35, "全栈工程师"]
console.log(Object.entries(person)); // [["name", "老李"], ["age", 35], ["job", "全栈工程师"]]
使用场景:
- 将对象转换为Map:
new Map(Object.entries(obj))
- 表单验证时检查是否有空值
- 配合数组方法进行链式操作
比如统计对象属性值的类型:
// 全栈老李的实用技巧
const typeCount = Object.values(person)
.map(value => typeof value)
.reduce((acc, type) => {
acc[type] = (acc[type] || 0) + 1;
return acc;
}, {});
console.log(typeCount); // { string: 2, number: 1 }
三、Object.fromEntries:数组变对象的"魔法"
这是ES2019新增的方法,可以看作是Object.entries
的逆操作:
// 全栈老李示例:键值对数组转对象
const entries = [
['name', '全栈老李'],
['age', 35],
['skills', ['JS', 'Node', 'React']]
];
const obj = Object.fromEntries(entries);
console.log(obj);
// {
// name: "全栈老李",
// age: 35,
// skills: ["JS", "Node", "React"]
// }
使用场景:
- 将URL查询参数转换为对象
- 处理Map结构转换为普通对象
- 配合
Object.entries
实现对象转换管道
比如处理URL参数:
// 全栈老李实战:解析URL参数
const paramsString = 'name=全栈老李&age=35&skill=JS';
const searchParams = new URLSearchParams(paramsString);
console.log(Object.fromEntries(searchParams));
// { name: "全栈老李", age: "35", skill: "JS" }
四、Object.is:比===更严格的相等判断
你可能觉得===
已经够严格了,但Object.is
在某些边界情况下更精确:
// 全栈老李的对比实验
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
使用场景:
- 需要精确比较+0和-0的场景
- 需要识别NaN的场景
- 实现不可变数据结构的比较
五、Object.getOwnPropertyDescriptors:属性的"完整档案"
这个方法可以获取对象属性的完整描述符(包括value、writable、enumerable、configurable等):
// 全栈老李示例:属性描述符查看
const obj = {
name: '全栈老李',
get age() {
return 35;
}
};
console.log(Object.getOwnPropertyDescriptors(obj));
// {
// name: {
// value: "全栈老李",
// writable: true,
// enumerable: true,
// configurable: true
// },
// age: {
// get: [Function: get age],
// set: undefined,
// enumerable: true,
// configurable: true
// }
// }
使用场景:
- 精确复制对象(包括getter/setter)
- 创建具有相同属性特性的新对象
- 高级属性操作和元编程
六、实战应用:实现一个深拷贝函数
结合几个方法,我们可以实现一个简单的深拷贝:
// 全栈老李的深拷贝实现(基础版)
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj);
}
if (obj instanceof RegExp) {
return new RegExp(obj);
}
const descriptors = Object.getOwnPropertyDescriptors(obj);
const clone = Object.create(
Object.getPrototypeOf(obj),
descriptors
);
Object.entries(descriptors).forEach(([key, descriptor]) => {
if (descriptor.value && typeof descriptor.value === 'object') {
clone[key] = deepClone(descriptor.value);
}
});
return clone;
}
const original = {
name: '全栈老李',
meta: {
skills: ['JS', 'Node'],
createdAt: new Date()
}
};
const cloned = deepClone(original);
console.log(cloned.meta === original.meta); // false —— 深拷贝成功!
课后作业:面试题挑战
题目:
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { c: 5, d: 6 };
const result = Object.assign({}, obj1, obj2, obj3);
console.log(result);
请问console.log输出什么?在评论区留下你的答案,我会随机抽几位同学的答案进行点评哦~
(提示:注意属性的覆盖顺序和Object.assign的特性)
我是全栈老李,一个资深Coder!
写码不易,如果你觉得有用,点赞 + 收藏 + 关注 走一波!感谢鼓励!🌹🌹🌹
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。