对象方法
对象方法
可选链式操作符(?.)
这是当对象上没有这个键的时候,不会报错,而是赋值undefined
const foo = { name: "zengbo" };
let a = foo.name?.toUpperCase(); // "ZENGBO"
let b = foo.name?.firstName?.toUpperCase(); // "undefined"
Object.groupBy() 对象分组
Object.groupBy() 方法是一项新添加的功能,允许我们按照特定属性将数组中的 对象分组,从而使数据处理变得更加容易。
const employees = [
{ name: "Alice", age: 25, department: "HR" },
{ name: "Bob", age: 30, department: "IT" },
{ name: "Charlie", age: 22, department: "HR" },
{ name: "David", age: 28, department: "Operations" },
{ name: "Eva", age: 35, department: "IT" }
];
const groupedByDepartment = Object.groupBy(employees, employee => employee.department);
console.log(groupedByDepartment);
这段代码的输出将会是:
{
"HR": [
{ "name": "Alice", "age": 25, "department": "HR" },
{ "name": "Charlie", "age": 22, "department": "HR" }
],
"IT": [
{ "name": "Bob", "age": 30, "department": "IT" },
{ "name": "Eva", "age": 35, "department": "IT" }
],
"Operations": [
{ "name": "David", "age": 28, "department": "Operations" }
]
}
示例:按条件分组
除了按属性简单分组,Object.groupBy() 还可以基于更复杂的条件进行分组。例如,按年龄范围分组。
const groupedByAgeRange = Object.groupBy(employees, employee => {
if (employee.age < 25) {
return 'Young';
} else if (employee.age >= 25 && employee.age <= 35) {
return 'Mid';
} else {
return 'Senior';
}
});
console.log(groupedByAgeRange);
输出结果为:
{
"Mid": [
{ "name": "Alice", "age": 25, "department": "HR" },
{ "name": "Bob", "age": 30, "department": "IT" },
{ "name": "David", "age": 28, "department": "Operations" },
{ "name": "Eva", "age": 35, "department": "IT" }
],
"Young": [
{ "name": "Charlie", "age": 22, "department": "HR" }
]
}
Object.assign() 对象合并
const arg1 = { a: 1, b: 2 };
const arg2 = { b: 4, c: 5 };
const arg = Object.assign(arg1, arg2);
console.log(arg);
// { a: 1, b: 4, c: 5 }
console.log(arg === arg1);
// true
Object.keys() 获取键名组成数组
案例1:键名不是数字情况 按正常顺序排序取值
var obj = {
p1: 123,
p2: 456
};
const rsun = Object.keys(obj)
console.log(rsun)
// ["p1", "p2"]
案例2:键名是数字情况 对象key为number的话,会从升序枚举返回
var obj = {
2: 123,
1: 456,
4: 333
};
const rsun = Object.keys(obj)
console.log(rsun)
// [ '1', '2', '4' ]
案例3:处理字符串,返回索引值数组
let str = "saasd字符串"
Object.keys(str)
// ["0", "1", "2", "3", "4", "5", "6", "7"]
Object.values() 获取键值组成数组
案例1:键名不是数字情况 按正常顺序排序取值
var obj = {
p1: 123,
p2: 456
};
const rsun = Object.values(obj)
console.log(rsun)
// [ 123, 456 ]
案例2:键名是数字情况 对象key为number的话,会从升序枚举返回
var obj = {
2: 123,
1: 456,
4: 333
};
const rsun = Object.values(obj)
console.log(rsun)
// [ 456, 123, 333 ]
Object.entries 返回一个数组
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组
const obj = {foo : "bar", baz : 10};
const rsun = Object.entries(obj)
console.log(rsun)
// [ [ 'foo', 'bar' ], [ 'baz', 10 ] ]
转换成Map结构
const obj = {foo : "bar", baz : 10};
const map = new Map(Object.entries(obj))
console.log(map);
// Map(2) { 'foo' => 'bar', 'baz' => 10 }
Object.is 判断严格相等
它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
Object.is('foo', 'foo') // true
Object.is({}, {}) // false
// 不同于 === 之处
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
Object.freeze() 冻结一个对象
Object.freeze()是ES5新增的特性,可以冻结一个对象,防止对象被修改。 freeze() 返回和传入的参数相同的对象。
注意:freeze() 是浅冻结
基本使用
var obj = {
name:'alley',
age:19,
sex:'男'
}
obj.__proto__.habit = '运动';
Object.freeze(obj);
// 不能添加新属性
obj.address = '北京'
console.log(obj) // {name: "alley", age: 19, sex: "男"}
// 不能删除原有属性
delete obj.age
console.log(obj) // {name: "alley", age: 19, sex: "男"}
// 不能修改已有属性的值
obj.name = 'dy_alley'
console.log(obj) // {name: "alley", age: 19, sex: "男"}
// 不能修改原型
obj.__proto__ = '随便什么值'
console.log(obj.__proto__) // {habit: "运动", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, …}
冻结数组
var arr = [1,2,3,4,5,6];
Object.freeze(arr);
arr[0] = 'alley';
console.log(arr); // [ 1,2,3,4,5].
不能删除现有属性
let obj = {foo : "bar", baz : 10};
Object.freeze(obj)
delete obj.baz
console.log(obj)
// { foo: 'bar', baz: 10 }
深度冻结 Object.freeze只能进行浅冻结,如果对象里面有对象的情况下则无法冻结
var obj = {
name:'alley',
info: {
age:19,
sex:'男'
}
}
Object.freeze(obj);
obj.name = 'dy_alley';
obj.info.age = 20;
console.log(obj); // {name:'alley',info:{age:20,sex:'男'}};
使用递归实现深度冻结
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).foreach( (key,i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
})
}
Object.isFrozen() 获取对象是否冻结
Object.isFrozen(obj)
Object.seal() 封闭一个对象
bject.seal()方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。 当前属性的值只要可写就可以改变。
不可以添加属性,但可以修改属性
let obj = {foo : "bar", baz : 10};
Object.seal(obj)
obj.url = "www.baidu.com"
obj.baz = '修改属性'
console.log(obj)
// { foo: 'bar', baz: '修改属性' }
不能删除现有属性
let obj = {foo : "bar", baz : 10};
Object.seal(obj)
delete obj.baz
console.log(obj)
// { foo: 'bar', baz: 10 }
Object.defineProperty不能扩展对象属性
let obj = {foo : "bar", baz : 10};
Object.seal(obj)
Object.defineProperty(obj,"sex",{value:"男"})
console.log(obj)
// 上面说到密封对象不可扩展,所以会报错
Object.isSealed() 判断是否是密封对象
let obj = {foo : "bar", baz : 10};
console.log(Object.isSealed(obj))
// false
Object.seal(obj)
console.log(Object.isSealed(obj))
// true
Object.preventExtensions() 对象不可扩展
Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性,但是可以修改已有属性
设置preventExtensions
let obj = {foo : "bar", baz : 10};
Object.preventExtensions(obj)
obj.url = 'www.baidu.com'
console.log(obj.url)
// undefined
不可扩展属性,但是可以修改现有属性
let obj = {foo : "bar", baz : 10};
Object.preventExtensions(obj)
obj.baz = '修改现有属性'
console.log(obj)
// { foo: 'bar', baz: '修改现有属性' }
可以删除(delete)现有属性
let obj = {foo : "bar", baz : 10};
Object.preventExtensions(obj)
delete obj.baz
console.log(obj)
// { foo: 'bar' }
Object.isExtensible()判断一个对象是否可扩展
let obj = {foo : "bar", baz : 10};
console.log(Object.isExtensible(obj))
// true
Object.preventExtensions(obj)
console.log(Object.isExtensible(obj))
// false
冻结对象和密封对象都是不可扩展的
let obj = {foo : "bar", baz : 10};
let sealad = Object.seal(obj)
let frozen = Object.freeze(obj)
console.log(Object.isExtensible(sealad),Object.isExtensible(frozen))
// false false