对象方法有哪些?
一、对象基础概念
- 定义: 对象(Object)是 JavaScript 中一种 键值对(key-value) 数据结构,用于存储一组有序或无序的数据。
- 特点:
- 键(key)可以是字符串或 Symbol。
- 值(value)可以是任意类型(基本类型或引用类型)。
- 对象是引用类型,赋值和拷贝默认是引用拷贝。
- 判断对象:
js
typeof obj === "object" && obj !== null; // 判断对象类型 ✅
Object.prototype.toString.call(obj); // "[object Object]"
二、ES5 常用方法
方法 | 功能 | 示例 | 是否修改原对象 |
---|---|---|---|
Object.keys(obj) | 返回对象自身可枚举属性名数组 | {a:1,b:2} → ['a','b'] | ❌ |
Object.values(obj) | 返回对象自身属性值数组 | {a:1,b:2} → [1,2] | ❌ |
Object.entries(obj) | 返回 [key,value] 数组 | {a:1,b:2} → [["a",1],["b",2]] | ❌ |
Object.assign(target, source) | 合并对象 | {a:1}, {b:2} → {a:1,b:2} | ✅ 修改 target |
Object.hasOwnProperty(key) | 判断是否拥有自身属性 | obj.hasOwnProperty('a') | ❌ |
Object.freeze(obj) | 冻结对象(不可改) | obj.a=2 不生效 | ✅ 改变 obj 状态 |
Object.seal(obj) | 密封对象(禁止新增/删除属性) | 可修改已有值 | ✅ 改变 obj 状态 |
Object.defineProperty(obj,key,desc) | 定义或修改属性描述符 | 控制 writable/enumerable/configurable | ✅ 改变 obj 状态 |
Object.getOwnPropertyDescriptor(obj,key) | 获取属性描述符 | {value:..., writable:...} | ❌ |
三、ES6 新增方法
方法 | 功能 | 示例 | 是否修改原对象 |
---|---|---|---|
Object.is(value1,value2) | 精确比较两个值 | Object.is(NaN,NaN) → true | ❌ |
Object.getOwnPropertySymbols(obj) | 获取对象的 Symbol 属性 | {[Symbol('s')]:1} → [Symbol(s)] | ❌ |
解构赋值 | 对象拆分 | let {a,b} = obj; | ❌ |
扩展运算符 ... | 合并或克隆对象 | {...obj1,...obj2} | ❌ |
Object.fromEntries() | 将 [key,value] 转回对象 | [['a',1]] → {a:1} | ❌ |
四、ES7(ES2016)新增方法
方法 | 功能 | 示例 | 是否修改原对象 |
---|---|---|---|
Object.values(obj) | 已在 ES5 后扩展,ES7 实用性增强 | {a:1} → [1] | ❌ |
Object.entries(obj) | 已在 ES5/ES6 后扩展,配合 fromEntries | {a:1} → [["a",1]] | ❌ |
WARNING
⚠️ 对象的核心方法在 ES5/ES6 已覆盖,ES7 并未新增大规模方法,更多是语法优化和迭代便利性。
五、原对象是否被破坏总结
方法类型 | 方法示例 | 是否破坏原对象 |
---|---|---|
修改原对象 | Object.assign(target, source) , Object.defineProperty(obj,key,desc) , Object.defineProperties(obj,props) , delete obj.key , Object.freeze(obj) , Object.seal(obj) | ✅ |
不修改原对象 | Object.keys(obj) , Object.values(obj) , Object.entries(obj) , Object.getOwnPropertyNames(obj) , Object.getOwnPropertySymbols(obj) , Object.getOwnPropertyDescriptor(obj,key) , Object.is(value1,value2) , {...obj} , Object.fromEntries(array) | ❌ |
六、前端面试常见拓展题
💬Q1: 对象如何浅拷贝和深拷贝?
考察点:引用类型拷贝
js
let obj = { a: 1, b: { c: 2 } };
// 浅拷贝
let shallow = { ...obj };
shallow.b.c = 100;
console.log(obj.b.c); // 100
// 深拷贝
let deep = JSON.parse(JSON.stringify(obj));
deep.b.c = 200;
console.log(obj.b.c); // 100
💬Q2: 如何合并多个对象?
考察点:Object.assign
/ 扩展运算符
js
let obj1 = { a: 1 };
let obj2 = { b: 2 };
let merged = { ...obj1, ...obj2 }; // {a:1,b:2}
let merged2 = Object.assign({}, obj1, obj2); // {a:1,b:2}
💬Q3: 如何判断对象是否为空?
考察点:属性长度、键数组判断
js
let obj = {};
Object.keys(obj).length === 0; // true
💬Q4: 对象与 Map 的区别?
考察点:键类型、迭代顺序、性能
区别 | Object | Map |
---|---|---|
键类型 | 字符串 / Symbol | 任意类型 |
有序 | 否 | 是(插入顺序) |
遍历 | for..in / Object.keys | map.forEach / for..of |
原型 | 有原型链 | 无原型链 |
💬Q5: 如何遍历对象(含 Symbol)?
考察点:属性类型区分
js
let sym = Symbol("s");
let obj = { a: 1, [sym]: 2 };
Object.keys(obj); // ["a"]
Object.getOwnPropertySymbols(obj); // [Symbol(s)]
Object.getOwnPropertyNames(obj); // ["a"]
💬Q6: 对象属性描述符和 defineProperty
考察点:控制对象属性特性
js
let obj = {};
Object.defineProperty(obj, "a", {
value: 1,
writable: false,
enumerable: true,
configurable: false,
});
obj.a = 2; // 不生效
console.log(obj.a); // 1
💬Q7: 对象扁平化/嵌套对象访问
考察点:嵌套数据结构
js
let obj = { a: { b: { c: 1 } } };
console.log(obj?.a?.b?.c); // 1 (可选链)
💬Q8: 对象的解构赋值与默认值
考察点:ES6 解构语法
js
let obj = { a: 1 };
let { a, b = 2 } = obj;
console.log(a, b); // 1,2
💬Q9: 对象动态属性/计算属性名
考察点:ES6 新特性
js
let key = "name";
let obj = { [key]: "Alice" };
console.log(obj.name); // "Alice"