Object API
一、对象创建方法
Object.create(proto, [propertiesObject])
创建一个新对象,指定其原型对象和属性。javascript// 以 obj 为原型创建新对象 const obj = { a: 1 }; const newObj = Object.create(obj); console.log(newObj.a); // 1(继承自原型) console.log(Object.getPrototypeOf(newObj) === obj); // true // 同时定义属性 const customObj = Object.create(null, { b: { value: 2, writable: true } // 可写属性 });Object.assign(target, ...sources)
将源对象的可枚举属性复制到目标对象,返回目标对象(==浅拷贝==)。javascriptconst target = { a: 1 }; const source1 = { b: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); console.log(target); // { a: 1, b: 2, c: 3 } // 浅拷贝示例(嵌套对象仅复制引用) const obj = { info: { name: "Alice" } }; const copy = Object.assign({}, obj); copy.info.name = "Bob"; console.log(obj.info.name); // "Bob"(原对象被修改)通过这种方式也可以实现添加一个方法的目的:
// 方式2:后期通过点语法/方括号添加(动态添加)
obj2.say = function() { console.log("说话"); };
obj2["run"] = () => console.log("跑步"); // 方括号支持动态键名
// 方式3:通过 Object.assign 批量添加
Object.assign(obj3, {
jump() { console.log("跳跃"); }
});- 使用对象字面量创建:
// 基础字面量创建
const person = {
name: "张三", // 属性键值对
age: 20,
sayHi: function() { // 方法
console.log(`Hi, ${this.name}`);
}
};- 使用关键字
new,调用构造函数:
const obj = new Object();//(构造函数方式)二、属性描述与操作
Object.defineProperty(obj, prop, descriptor)
为对象定义或修改属性,并设置属性描述符(如是否可写、可枚举等)。 与直接为一个对象的属性赋值(o.a = 3)不同,Object.defineProperty 可更为精确,拥有更多选项地为对象属性赋值
属性描述符拥有两种: 数据描述符与存取描述符对象的属性配置
const obj = {};
Object.defineProperty(obj, "name", {
value: "John",
writable: false, // 不可修改
enumerable: true, // 可枚举(可被 for...in 遍历)
configurable: false // 不可删除或修改描述符
});
obj.name = "Alice"; // 无效(严格模式下报错)
console.log(obj.name); // "John"Object.getOwnPropertyDescriptor(obj, prop)
获取对象指定属性的描述符。javascriptconst obj = { age: 20 }; const desc = Object.getOwnPropertyDescriptor(obj, "age"); console.log(desc); // { // value: 20, // writable: true, // enumerable: true, // configurable: true // }Object.keys(obj)/Object.values(obj)/Object.entries(obj)keys:返回对象自身==可枚举==属性的键名数组。Object.getOwnPropertyNames():列出==所有属性值(包括可枚举与不可枚举)==。在Object.defineProperty中的选项enumerable可定义属性是否可枚举values:返回对象自身可枚举属性的键值数组。entries:返回对象自身可枚举属性的[键, 值]数组。
javascriptconst user = { name: "Bob", age: 30 }; console.log(Object.keys(user)); // ["name", "age"] console.log(Object.values(user)); // ["Bob", 30] console.log(Object.entries(user)); // [["name", "Bob"], ["age", 30]]
三、原型与继承
Object.getPrototypeOf(obj)
获取对象的原型(__proto__的标准替代方法)。javascriptconst arr = []; console.log(Object.getPrototypeOf(arr) === Array.prototype); // trueObject.setPrototypeOf(obj, proto)
设置对象的原型(谨慎使用,可能影响性能)。javascriptconst obj = {}; const proto = { greet: () => "Hello" }; Object.setPrototypeOf(obj, proto); console.log(obj.greet()); // "Hello"Object.prototype.isPrototypeOf(obj)
判断当前对象是否为目标对象的原型。javascriptconst proto = {}; const obj = Object.create(proto); console.log(proto.isPrototypeOf(obj)); // true
四、对象检查与比较
Object.prototype.hasOwnProperty(prop)
判断对象自身是否包含指定属性(==不包括继承的属性==)。javascriptconst obj = { a: 1 }; console.log(obj.hasOwnProperty("a")); // true console.log(obj.hasOwnProperty("toString")); // false(继承自 Object)Object.is(value1, value2)
判断两个值是否严格相等(类似===,但处理特殊值更准确)。javascriptconsole.log(Object.is(1, 1)); // true console.log(Object.is(NaN, NaN)); // true(=== 会返回 false) console.log(Object.is(0, -0)); // false(=== 会返回 true)
五、其他常用方法
Object.freeze(obj)
冻结对象:使其属性不可修改、删除,也不能添加新属性。javascriptconst obj = { a: 1 }; Object.freeze(obj); obj.a = 2; // 无效 delete obj.a; // 无效 console.log(obj.a); // 1Object.seal(obj)
密封对象:属性不可删除,也不能添加新属性,但可修改现有属性的值。javascriptconst obj = { a: 1 }; Object.seal(obj); obj.a = 2; // 有效 delete obj.a; // 无效 console.log(obj.a); // 2Object.prototype.toString()
返回对象的字符串表示(可用于准确判断数据类型)。javascriptconsole.log(Object.prototype.toString.call(123)); // "[object Number]" console.log(Object.prototype.toString.call([])); // "[object Array]" console.log(Object.prototype.toString.call(null)); // "[object Null]"
总结
- 对象创建与复制:
Object.create()、Object.assign() - 属性操作:
defineProperty()、getOwnPropertyDescriptor()、keys()/values()/entries() - 原型管理:
getPrototypeOf()、setPrototypeOf()、isPrototypeOf() - 对象保护:
freeze()(冻结)、seal()(密封) - 类型判断:
toString()(比typeof更准确)
这些方法是操作对象的基础,尤其在处理复杂对象结构或需要精确控制属性行为时非常有用。
对象的keys,values,entries
对于普通对象,下列这些方法是可用的:
- Object.keys(obj) —— 返回一个包含该对象所有的键的数组。
- Object.values(obj) —— 返回一个包含该对象所有的值的数组。
- Object.entries(obj) —— 返回一个包含该对象所有 [key, value] 键值对的数组。
……但是请注意区别(比如说跟 map 的区别):
| Map | Object |
|---|---|
| 调用语法 | map.keys() |
| 返回值 | 可迭代对象 |
第二个区别是 Object.* 方法返回的是“真正的”数组对象,而不只是一个可迭代对象。 在 JavaScript 中,对象是所有复杂结构的基础。因此,我们可能有一个自己创建的对象,比如 data,并实现了它自己的 data.values() 方法。同时,我们依然可以对它调用 Object.values(data) 方法。