属性判断
说明
可枚举:属性的 enumerable 值为 true
自身属性:未特别说明均为自有可枚举和不可枚举属性(非继承属性)
let obj = {
name: 'orange',
age: 18
}
// 添加一个不可枚举属性
Object.defineProperty(obj, 'weight', {
value: 140,
enumerable: false // 不可枚举
})
// 在原型上添加一个可枚举属性
Object.prototype.height = 180;
// 新增一个值为 undefined 的属性
obj.birthday = undefined;
PS: 下面示例均是基于上方基础代码进行判断的
自有属性(枚举、不可枚举)及继承属性
- 正常访问属性形式【
.、[]】 in运算符
console.log(obj.name !== undefined) // 自身属性存在(true)
console.log(obj['weight'] !== undefined) // 不可枚举属性(true)
console.log(obj.height !== undefined) // 原型链上继承的属性(true)
console.log(obj.gender !== undefined) // gender 属性不存在(false)
console.log(obj.birthday !== undefined) // 值为 undefined 的属性(false)
'name' in obj // 自身属性(true)
'weight' in obj // 不可枚举属性(true)
'height' in obj // 原型链上继承的属性(true)
'birthday' in obj // 值为 undefined 的属性(true)
注意⚠️
- 特殊情况,正常访问属性形式如果值为
undefined的属性,是不会返回预期结果 in运算符对于值为undefined的属性也可以进行判断(对像是否含有某属性)- 不能准确区分是自有属性还是原型链上的继承属性。如果想要检测自有属性是否存在时,需要使用
Object.hasOwnProperty()
自有属性(枚举、不可枚举)
Object.hasOwnProperty() 判断属性是否为对象自有属性(非继承属性)
obj.hasOwnProperty('name') // 自身属性(true)
obj.hasOwnProperty('weight') // 可枚举属性(true)
obj.hasOwnProperty('birthday') // 值为 undefined 属性(true)
obj.hasOwnProperty('height') // 原型链上继承的属性(false)
自身属性(可枚举)
Object.keys() 返回对象可枚举自有属性(不含不可枚举、继承和 Symbol 属性)
对象遍历
- 遍历对象 所有自有和继承属性(可枚举),使用
for...in - 遍历对象 所有自有属性(可枚举、不可枚举),使用
Object.getOwnPropertyNames() - 遍历对象 所有自有 Symbol 属性,使用
Object.getOwnPropertySymbols() - 遍历对象 所有自有属性(包含 Symbol 属性),使用
Reflect.ownKeys() - 遍历对象 所有自有属性(可枚举),使用
Object.keys()或for...in + Object.hasOwnProperty() - 获取对象 所有继承属性(可枚举),可以使用
for...in + Object.keys() - 获取对象 所有属性(可枚举、不可枚举和继承),使用
for...in + Object.getOwnPropertyNames(obj)或for...in + Object.keys() + Object.getOwnPropertyNames(obj)
for...in
遍历对象所有自有和继承的可枚举属性
for (let key in obj) {
console.log(key, obj[key])
}
Object.keys()
遍历对象,返回所有可枚举自有属性(不含 Symbol 属性)值数组
for (key of Object.keys(obj)) { // 遍历对象 key 值
console.log(key, obj[key]);
}
for...of
遍历所有实现了 Iterator 接口的迭代器对象,主要包含有 Array、Set 和 Map 结构、类数组对象(比如 arguments 对象、DOM NodeList 对象)、字符串等。
注意⚠️:不能直接用来遍历对象
可通过结合 Object.keys(obj)、Object.values(obj) 和 Object.entries(obj) 方法先转化再进行遍历
for (value of Object.values(obj)) { // 遍历对象 value 值
console.log(value); // orange 18 undefined
}
for ([key, value] of Object.entries(obj)) { // 遍历对象 key、value 值
console.log(key, value);
}
Object.getOwnPropertyNames()
遍历对象,返回所有自有属性(不含 Symbol 属性) key 值数组
Object.getOwnPropertyNames(obj)
Object.getOwnPropertySymbols()
遍历对象,返回所有 自有 Symbol 属性 组成的数组
Reflect.ownKeys()
遍历对象,返回所有自有属性(包含 Symbol 属性)组成的数组,等价于:Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(target))
拓展
for...in + Object.getOwnPropertyNames()
获取所有属性名(自有属性及继承属性)
const getAllPropertyNames = (obj) => {
// 复制一份所有自有属性
let props = Object.assign([], Object.getOwnPropertyNames(obj))
// 得到所有的可枚举属性(自有的和继承的属性)
for (let key in obj) {
// 过滤自有的不可枚举属性(获取继承可枚举属性)
if (!Object.getOwnPropertyNames(obj).includes(key)) {
props.push(key)
}
}
return props;
};
console.log(getAllPropertyNames(obj);)