本文详细解析JavaScript对象30个项目中大概率会用到的方法,按照使用场景结合功能,参数,返回值,使用方法,兼容性这几个方面一一刨析,一次搞懂,使用时按场景需求对应查看即可。
开篇前先说下属性描述符(挺重要,能辅助解决疑难杂症):
js
{
value: any, // 属性值
writable: Boolean, // 是否可修改
enumerable: Boolean, // 是否可枚举
configurable: Boolean, // 是否可删除或修改特性
get: Function, // getter函数
set: Function // setter函数
}
//需要注意的是,get 和 set 以及 value 和 writable 这两组是互斥的。也就是说,一个属性描述符不能同时包含 get、set 和 value、writable。如果设置了 get 和 set,就不能再设置 value 和 writable;反之,如果设置了 value 和 writable,就不能再设置 `get` 和 `set`
一. Object 构造函数方法
1.Object.assign()
- 功能:将所有可枚举属性的值从一个或多个源对象复制到目标对象
- 参数 :
Object.assign(target, ...sources)
目标对象,一个或多个源对象 - 返回值:修改后的目标对象
- 示例:
js
var obj1 = {a:1,b:2};
var obj2 = {c:3,d:4};
var obj3 = {e:5,f:6};
var obj4 = Object.assign({},obj1,obj2,obj3);
console.log(obj4);//{ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
- 兼容性:ES6 (ES2015) 引入,IE不支持
2.Object.create()
-
功能:创建一个新对象,使用现有的对象来提供新创建对象的__proto__
-
参数 :
Object.create(proto[, propertiesObject])
新对象的原型对象,可选的属性描述符对象 -
返回值:新创建的对象
-
示例 :
jsvar person = { name: '张三', age: 20, sex: '男' } var person1 = Object.create(person,{ name:{ value:'张三1', writable: true, enumerable: true, configurable: true } }) console.log(person1.name);//张三1 console.log(person1.age);//20 通过原型链访问 console.log(person1.sex);//男 通过原型链访问 console.log(person1.__proto__ === person);//true
-
兼容性:ES5 引入,IE9+支持
3.Object.defineProperties()
-
功能:直接在一个对象上定义新的属性或修改现有属性,并返回该对象
-
参数 :
Object.defineProperties(obj, props)
要修改的对象,包含属性描述符的对象 -
返回值:修改后的对象
-
示例 :
js//Object.defineProperties()是 JavaScript 中用于批量定义或修改对象属性的方法,与下面的Object.defineProperty()方法类似但支持同时操作多个属性 // 可解决的问题 // 1.批量属性控制:避免重复调用Object.defineProperty() // 2.配置集中化:统一管理相关属性的特性(如所有配置项不可删除) // 3.性能优化:减少多次属性定义的开销 // 4.代码可读性:直观展示一组属性的关联性 var person = { name: '张三', sex: '男' } Object.defineProperties(person,{ aaa:{ value:'45', writable: true, enumerable: true, }, name:{ value:'张三1', writable: true, enumerable: true, configurable: true } }) for(let key in person){ console.log(key,person[key]) // name 张三1 sex 男 aaa 45 }
-
兼容性:ES5 引入,IE9+支持
4.Object.defineProperty()
-
功能:直接在一个对象上定义一个新属性,或修改一个对象的现有属性,并返回该对象
-
参数 :
Object.defineProperty(obj, prop, descriptor)
要定义属性的对象,要定义或修改的属性名称,属性描述符 -
返回值:修改后的对象
-
示例 :
js// 实现属性监听(Vue 2响应式原理简化版) var data = { name: '' }; Object.defineProperty(data, 'name', { get() { console.log('获取name'); return this._name; }, set(val) { console.log('设置name:', val); this._name = val; } }); data.name = 'Alice'; // 触发setter console.log(data.name); // 触发getter // 创建不可变常量 var obj = {}; Object.defineProperty(obj, 'num', { value: 3.1415, writable: false, enumerable: true }); obj.num = 100; // 更改会失败(严格模式报错) console.log(obj.num); // 3.1415 //还是原来的值 // 隐藏敏感属性 var user = {}; Object.defineProperty(user, 'password', { value: '123456', enumerable: false // 不会被for-in或Object.keys遍历 }); console.log(Object.keys(user)); // []
-
兼容性:ES5 引入,IE8+支持
5.Object.entries()
-
功能:返回一个给定对象自身可枚举属性的键值对数组
-
参数 :
Object.entries(obj)
要返回其可枚举属性键值对的对象 -
返回值 :二维数组,每个子数组为
[key, value]
形式 -
示例 :
jsconst obj = { a: 1, b: 2, c: 3 }; console.log(Object.entries(obj)); // [['a', 1], ['b', 2], ['c', 3]] // 非对象参数:原始类型(如字符串)会先被转为包装对象 console.log(Object.entries('hi')); // [['0', 'h'], ['1', 'i']]
-
兼容性:ES8 (ES2017) 引入,IE不支持
6.Object.freeze()
-
功能:冻结一个对象,使其不能添加新属性、删除属性或修改现有属性
-
参数 :
Object.freeze(obj)
要冻结的对象 -
返回值:被冻结的对象
-
示例 :
jsvar obj = { a: 1 }; Object.freeze(obj); obj.a = 22; // 严格模式下会抛出错误 console.log(obj.a); // 1 不会被更改 console.log(Object.isFrozen(obj)); // true
-
兼容性:ES5 引入,IE9+支持
7.Object.fromEntries()
-
功能:把键值对列表转换为一个对象
-
参数 :
Object.fromEntries(iterable)
可迭代对象,其元素为长度为2的数组 -
返回值:新对象
-
示例 :
js// Map 转对象 var map = new Map([['name', 'Alice'], ['age', 25]]); console.log(Object.fromEntries(map)); // { name: "Alice", age: 25 } // 数组数据处理 var arr = [['aa', 10], ['bb', 20]]; console.log(Object.fromEntries(arr)); // { aa: 10, bb: 20 } //对象属性转换 var user = { firstName: 'aa', lastName: 'bb' }; var renamed = Object.fromEntries( Object.entries(user).map(([key, val]) => [`_${key}`, val]) ); console.log(renamed); // { _firstName: "aa", _lastName: "bb" }
-
兼容性:ES10 (ES2019) 引入,IE不支持
8.Object.getOwnPropertyDescriptor()
-
功能:获取对象特定属性的描述符的方法
-
参数 :
Object.getOwnPropertyDescriptor(obj, prop)
需要查找其属性描述符的对象,要查找的属性名称 -
返回值:包含所有属性描述符的对象(键为属性名,值为描述符对象)
-
示例 :
jsvar obj = { age: 42, name:"李四"}; var descriptor = Object.getOwnPropertyDescriptor(obj, 'age'); console.log(descriptor); // { value: 42, writable: true, enumerable: true, configurable: true }
-
兼容性:ES5+
9.Object.getOwnPropertyDescriptors()
-
功能:获取对象所有自身属性的完整描述符的方法
-
参数 :
Object.getOwnPropertyDescriptors(obj)
任意对象 -
返回值:包含所有属性描述符的对象
-
示例 :
jsvar obj = { age:42, name:'张三'}; var descriptor = Object.getOwnPropertyDescriptors(obj); console.log(descriptor); // { // age: { value: 42, writable: true, enumerable: true, configurable: true }, // name: { value: '张三', writable: true, enumerable: true, configurable: true } // }
-
兼容性:ES2017+
10.Object.getOwnPropertyNames()
-
功能 :获取所有自有属性名(包括不可枚举属性,如
length
) -
参数 :
Object.getOwnPropertyNames(obj)
要获取属性名的对象 -
返回值:包含所有自身属性名称的数组
-
示例 :
js// 获取对象所有属性(含不可枚举) var obj = { a: 1, b: 2 }; Object.defineProperty(obj, 'cc', { value: 'iscc', enumerable: false }); var props = Object.getOwnPropertyNames(obj); console.log(props); // [ 'a', 'b', 'cc' ] //检测数组特殊属性 var arr = ['a', 'b', 'c']; console.log(Object.getOwnPropertyNames(arr));//[ '0', '1', '2', 'length' ]
-
兼容性:ES5+
11. Object.getOwnPropertySymbols()
-
功能:返回一个给定对象自身的所有 Symbol 属性的数组
-
参数 :
Object.getOwnPropertySymbols(obj)
要获取 Symbol 属性的对象 -
返回值:包含所有 Symbol 属性的数组
-
示例 :
jsvar obj = {}; var a = Symbol('a'); var b = Symbol.for('b'); obj[a] = 'localSymbol'; obj[b] = 'globalSymbol'; var objectSymbols = Object.getOwnPropertySymbols(obj); console.log(objectSymbols); // [Symbol(a), Symbol(b)]
-
兼容性:ES6+
12.Object.getPrototypeOf()
-
功能:返回指定对象的原型
-
参数 :
Object.getPrototypeOf(obj)
要获取原型的对象 -
返回值:给定对象的原型
-
示例 :
jsvar obj = {}; var proto = Object.getPrototypeOf(obj); console.log(proto === Object.prototype); // true //检查对象继承关系 function isArrayLike(obj) { let proto = Object.getPrototypeOf(obj); return proto === Array.prototype || proto === Object.prototype; } //框架开发(原型污染防护) function sanitizeObject(obj) { if (Object.getPrototypeOf(obj) !== Object.prototype) { throw new Error('Invalid prototype chain'); } }
-
兼容性:ES5+
13.Object.hasOwn()
-
功能:判断对象自身是否具有指定的属性
-
参数 :
Object.hasOwn(obj, prop)
要测试的对象,要检查的属性名(字符串或 Symbol) -
返回值:布尔值
-
示例 :
jsvar obj = { a: '1' }; console.log(Object.hasOwn(obj, 'a')); // true console.log(Object.hasOwn(obj, 'toString')); // false // 安全检查对象属性 function safeGet(obj, prop) { return Object.hasOwn(obj, prop) ? obj[prop] : undefined; } // 防御式编程(避免原型污染) function mergeSafe(target, source) { for (const key in source) { if (Object.hasOwn(source, key)) { target[key] = source[key]; } } }
-
兼容性:ES2022+
14.Object.hasOwnProperty()
-
功能:判断对象自身是否具有指定的属性(不包括继承的属性)
-
参数 :
Object.hasOwnProperty(prop)
要检查的属性名(字符串或 Symbol) -
返回值:布尔值
-
示例 :
jsvar obj = { a: 1 }; console.log(obj.hasOwnProperty('a')); // true console.log(obj.hasOwnProperty('toString')); // false(继承属性) //过滤原型链属性 function getOwnProps(obj) { return Object.keys(obj).filter(key => obj.hasOwnProperty(key) ); } //框架开发(属性白名单校验) class Model { constructor(data) { const allowedProps = ['id', 'name']; for (const key in data) { if (!allowedProps.includes(key) || !data.hasOwnProperty(key)) { throw new Error(`Invalid property: ${key}`); } } } }
-
兼容性:全平台支持
15.Object.is()
-
功能:判断两个值是否为同一个值
-
参数 :
Object.is(value1, value2)
要比较的两个值 -
返回值:布尔值
-
示例 :
js// 1.精确相等比较: // 解决 === 的两个缺陷: // NaN === NaN → false(错误) // 0 === -0 → true(可能不符合预期) // 2.替代 === 的特殊场景: // 需要严格区分 +0 和 -0 // 需要明确判断 NaN console.log(Object.is(5, 5)); // true console.log(Object.is(NaN, NaN)); // true(与 === 不同) console.log(Object.is(0, -0)); // false(与 === 不同) console.log(Object.is('a', 'a')); // true
-
兼容性:ES2015+
16.Object.isExtensible()
-
功能:判断一个对象是否是可扩展的(即能否添加新属性)
-
参数 :
Object.isExtensible(obj)
要检查的对象 -
返回值:布尔值
-
示例 :
jsvar obj = { a: 1 }; console.log(Object.isExtensible(obj)); // true(默认可扩展) Object.preventExtensions(obj); console.log(Object.isExtensible(obj)); // false(锁定后不可扩展) // 尝试添加属性(严格模式报错) obj.b = 2; // 非严格模式默认失败,不会报错 console.log(obj.b); // undefined
-
兼容性:ES5+,IE9+
17.Object.isFrozen()
-
功能:判断一个对象是否被冻结(即完全禁止修改属性)
-
参数 :
Object.isFrozen(obj)
要检查的对象 -
返回值:布尔值
-
示例 :
jsvar obj = { a: 1, nested: { b: 2 } }; Object.freeze(obj); console.log(Object.isFrozen(obj)); // true(对象被冻结,不能删除或修改属性) console.log(Object.isFrozen(obj.nested)); // false(嵌套对象未冻结) //数据完整性检查 const sharedData = { userSettings: { theme: "dark", language: "en" } }; function processSharedData(data) { if (Object.isFrozen(data)) { console.log("数据已冻结,以只读方式处理"); // 进行只读操作 } else { console.log("数据可能被修改,谨慎处理"); } } // 假设某个地方冻结了 sharedData Object.freeze(sharedData); processSharedData(sharedData);
-
兼容性:ES5+,IE9+
18.Object.isSealed()
-
功能:判断一个对象是否被密封
-
参数 :
Object.isSealed(obj)
要检查的对象 -
返回值:布尔值
-
示例 :
jslet normalObject = { a: 1 }; console.log(Object.isSealed(normalObject)); // 输出 false,因为普通对象是可扩展且属性可配置的 // 使用 Object.seal() 方法密封对象 let sealedObject = { b: 2 }; Object.seal(sealedObject); console.log(Object.isSealed(sealedObject)); // 输出 true,该对象已被密封,不能添加新属性,不能删除现有属性,现有属性的 configurable 特性为 false // 创建一个冻结对象 let frozenObject = { c: 3 }; Object.freeze(frozenObject); console.log(Object.isSealed(frozenObject)); // 输出 true,冻结对象也是密封的,因为它不能添加新属性,不能删除现有属性,所有属性的 configurable 和 writable 特性都是 false
-
兼容性:ES5+
19.Object.keys()
-
功能:返回一个由一个给定对象的自身可枚举属性组成的数组
-
参数 :
Object.keys(obj)
要返回其可枚举属性名的对象 -
返回值:包含对象所有可枚举属性名称的数组
-
示例 :
jsvar obj = { a: 1, b: 2, c: 3 }; console.log(Object.keys(obj)); // [ 'a', 'b', 'c' ] // 对象属性操作 const person = { name: 'John', age: 30, city: 'New York', email: 'john@123.com' }; // 获取属性数组并过滤出包含 "name" 的属性 const filteredKeys = Object.keys(person).filter((key) => key.includes('name')); console.log(filteredKeys); // ['name']
-
兼容性:ES5+
20.Object.preventExtensions()
-
功能:让一个对象变的不可扩展,也就是永远不能再添加新的属性(用于防止一个对象再添加新的属性)
-
参数 :
Object.preventExtensions(obj)
要变得不可扩展的对象 -
返回值:已经不可扩展的对象
-
示例 :
jsvar myObject = { name: 'John', age: 30 }; // 使对象不可扩展 Object.preventExtensions(myObject); // 尝试添加新属性 myObject.newProperty = 'New Value'; // 在非严格模式下,上述操作不会报错,但新属性不会添加成功 // 在严格模式下,会抛出 TypeError 错误 console.log(myObject); // { name: 'John', age: 30 },新属性没有被添加
-
兼容性:ES5+,IE9+
21.Object.seal()
-
功能:密封一个对象,阻止添加新属性并将所有现有属性标记为不可配置
-
参数 :
Object.seal(obj)
要被密封的对象 -
返回值:被密封的对象
-
示例 :
js// 此方法可用于解决:1.确保对象结构稳定(防止意外修改)2.隐藏实现细节(防御性编程)3.提升性能 var myObject = { name: 'John', age: 30 }; // 密封对象 var sealedObject = Object.seal(myObject); // 尝试添加新属性,不会成功 sealedObject.newProperty = 'New Value'; console.log(sealedObject.newProperty); // undefined // 尝试删除现有属性,不会成功 delete sealedObject.age; console.log(sealedObject.age); // 30 // 可以修改现有属性的值 sealedObject.age = 31; console.log(sealedObject.age); // 31
-
兼容性:ES5+
22.Object.setPrototypeOf()
-
功能 :设置一个指定对象的原型到另一个对象或null(即
[[Prototype]]
内部属性) -
参数 :
Object.setPrototypeOf(obj, prototype)
要设置其原型的对象,该对象的新原型 -
返回值:修改后的对象
-
示例 :
js// 创建一个原型对象 var animalPrototype = { speak() { console.log('I am an animal'); } }; // 创建一个普通对象 var dog = { name: 'Buddy' }; // 使用 Object.setPrototypeOf 设置 dog 对象的原型 Object.setPrototypeOf(dog, animalPrototype); // 现在 dog 对象可以调用原型的方法 dog.speak(); // I am an animal // 修改对象的行为 var scenarioAPrototype = { performAction() { console.log('Performing action in scenario A'); } }; // 业务场景 B 的原型 var scenarioBPrototype = { performAction() { console.log('Performing action in scenario B'); } }; // 一个普通对象 var myObject = {}; // 设置为场景 A 的行为 Object.setPrototypeOf(myObject, scenarioAPrototype); myObject.performAction(); // Performing action in scenario A // 动态切换到场景 B 的行为 Object.setPrototypeOf(myObject, scenarioBPrototype); myObject.performAction(); // Performing action in scenario B
-
兼容性:ES6+
23.Object.values()
-
功能:返回一个给定对象自身的所有可枚举属性值的数组
-
参数 :
Object.values(obj)
要返回其可枚举属性值的对象 -
返回值:包含对象所有可枚举属性值的数组
-
示例 :
jsvar obj = { a: 1, b: 2, c: 3 }; console.log(Object.values(obj)); // [1, 2, 3] // 遍历对象值 var prices = { apple: 1.5, banana: 0.5, orange: 2 }; var totalPrice = Object.values(prices).reduce((acc, price) => acc + price, 0); console.log(totalPrice); // 输出: 4 // 数据结构转换 var data = { series1: [10, 20, 30], series2: [15, 25, 35] }; var valuesArray = Object.values(data); // 此时 valuesArray 可以直接用于图表绘制的数据输入 console.log(valuesArray); // 输出: [[10, 20, 30], [15, 25, 35]]
-
兼容性:ES2017+
二. 实例方法
24.obj.hasOwnProperty()
-
功能:判断对象自身是否具有指定的属性
-
参数 :
obj.hasOwnProperty(prop)
要检查的属性名 -
返回值:布尔值
-
示例 :
jsvar obj = { a: '1' }; console.log(obj.hasOwnProperty('a')); // true console.log(obj.hasOwnProperty('b')); // false
-
兼容性:所有版本
25.obj.isPrototypeOf()
-
功能:判断调用对象是否在另一个对象的原型链上
-
参数 :
obj.isPrototypeOf(obj)
要检查的对象 -
返回值:布尔值
-
示例 :
jsconst animal = { speak() { console.log('I can speak'); } }; const dog = { bark() { console.log('Woof!'); } }; // 设置 dog 的原型为 animal Object.setPrototypeOf(dog, animal); console.log(animal.isPrototypeOf(dog)); // true,因为 animal 是 dog 的原型对象
-
兼容性:所有版本
26.obj.propertyIsEnumerable()
-
功能:判断一个对象自身属性(非继承属性)是否可枚举
-
参数 :
obj.propertyIsEnumerable(prop)
要检查的属性名 -
返回值:布尔值
-
示例 :
jsvar myObj = { foo: 'bar', baz: 42 }; // 检查 'foo' 属性是否可枚举 console.log(myObj.propertyIsEnumerable('foo')); // true // 创建一个不可枚举的属性 Object.defineProperty(myObj, 'qux', { value: 'quux', enumerable: false }); // 检查 'qux' 属性是否可枚举 console.log(myObj.propertyIsEnumerable('qux')); // false // 检查继承的属性,例如 'toString' console.log(myObj.propertyIsEnumerable('toString')); // false
-
兼容性:所有版本
27.obj.toLocaleString()
-
功能:返回对象的字符串表示,该字符串与执行环境的地区对应
-
参数:无
-
返回值:对象的字符串表示
-
示例 :
js// 1. 数组的 toLocaleString() 方法 var fruits = ['apple', 'banana', 'cherry']; var result = fruits.toLocaleString(); console.log(result); // 输出类似 apple,banana,cherry 分隔符取决于本地环境 // 2. 日期的 toLocaleString() 方法 var now = new Date(); var dateString = now.toLocaleString(); console.log(dateString); // 输出类似 2023/10/31 15:30:00,格式取决于本地环境 // 3.数字的 toLocaleString() 方法 var number = 1234567.89; var formattedNumber = number.toLocaleString(); console.log(formattedNumber); // 输出类似 1,234,567.89,分隔符取决于本地环境
-
兼容性:所有版本
28.obj.toString()
-
功能:返回对象的字符串表示
-
参数:无
-
返回值:对象的字符串表示
-
示例 :
js// 普通对象 var person = { name: 'John', age: 30 }; console.log(person.toString()); // [object Object] // 数组对象 var arr = [1, 2, 3]; console.log(arr.toString()); // 1,2,3 // 日期对象 var date = new Date(); console.log(date.toString()); // Wed Sep 20 2025 11:40:15 GMT+0800 (中国标准时间)
-
兼容性:所有版本
29.obj.valueOf()
-
功能:返回对象的原始值
-
参数:无
-
返回值:对象的原始值
-
示例 :
js// Number 对象 var numObj = new Number(10); console.log(numObj.valueOf()); // 10 // String 对象 var strObj = new String('Hello'); console.log(strObj.valueOf()); // Hello // Boolean 对象 var boolObj = new Boolean(true); console.log(boolObj.valueOf());// true // Date 对象 var dateObj = new Date(); console.log(dateObj.valueOf()); // 1695890000000 // Array var arrObj = [1, 2, 3]; console.log(arrObj.valueOf()); // [1, 2, 3] // Object var obj = { name: 'John', age: 30 }; console.log(obj.valueOf());// { name: 'John', age: 30 }
-
兼容性:所有版本
三. 静态属性
30.Object.prototype
-
功能 :
Object.prototype
并不是一个方法,而是一个对象。它是所有对象的原型,几乎所有 JavaScript 对象都继承自Object.prototype
。这意味着所有对象都可以访问Object.prototype
上定义的属性和方法 -
示例 :
js// 所有对象都可以访问 Object.prototype 上的属性和方法。例如 toString 方法: var myObject = {name: 'Alice'}; console.log(myObject.toString()); // [object Object] 返回一个描述对象的字符串 // 在对象中覆盖原型方法(以自定义 toString 方法为例) var newObject = { toString: function() { return 'This is a custom toString for newObject'; } }; console.log(newObject.toString()); // This is a custom toString for newObject // 添加自定义方法到 Object.prototype(不推荐常规使用,但了解其原理) Object.prototype.customMethod = function() { return 'This is a custom method added to Object.prototype'; }; var testObject = {}; console.log(testObject.customMethod()); // This is a custom method added to Object.prototype
-
兼容性:所有版本
要想写出优雅的通用方法,以上这些方法是相当主要,它涵盖了 JavaScript 对象操作的基本上全部的主要功能,从基本的属性访问到高级的对象控制,每个方法都有其特定的用途和适用场景,可以根据项目需求结合兼容性选择性使用。