本文详细解析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]) 新对象的原型对象,可选的属性描述符对象
返回值:新创建的对象
示例 :
js
复制代码
var 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] 形式
示例 :
js
复制代码
const 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) 要冻结的对象
返回值:被冻结的对象
示例 :
js
复制代码
var 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) 需要查找其属性描述符的对象,要查找的属性名称
返回值:包含所有属性描述符的对象(键为属性名,值为描述符对象)
示例 :
js
复制代码
var 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) 任意对象
返回值:包含所有属性描述符的对象
示例 :
js
复制代码
var 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 属性的数组
示例 :
js
复制代码
var 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) 要获取原型的对象
返回值:给定对象的原型
示例 :
js
复制代码
var 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)
返回值:布尔值
示例 :
js
复制代码
var 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)
返回值:布尔值
示例 :
js
复制代码
var 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) 要检查的对象
返回值:布尔值
示例 :
js
复制代码
var 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) 要检查的对象
返回值:布尔值
示例 :
js
复制代码
var 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) 要检查的对象
返回值:布尔值
示例 :
js
复制代码
let 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) 要返回其可枚举属性名的对象
返回值:包含对象所有可枚举属性名称的数组
示例 :
js
复制代码
var 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) 要变得不可扩展的对象
返回值:已经不可扩展的对象
示例 :
js
复制代码
var 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) 要返回其可枚举属性值的对象
返回值:包含对象所有可枚举属性值的数组
示例 :
js
复制代码
var 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) 要检查的属性名
返回值:布尔值
示例 :
js
复制代码
var obj = { a: '1' };
console.log(obj.hasOwnProperty('a')); // true
console.log(obj.hasOwnProperty('b')); // false
兼容性:所有版本
25.obj.isPrototypeOf()
功能:判断调用对象是否在另一个对象的原型链上
参数 :obj.isPrototypeOf(obj) 要检查的对象
返回值:布尔值
示例 :
js
复制代码
const 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) 要检查的属性名
返回值:布尔值
示例 :
js
复制代码
var 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 对象操作的基本上全部的主要功能,从基本的属性访问到高级的对象控制,每个方法都有其特定的用途和适用场景,可以根据项目需求结合兼容性选择性使用。