判断属性是否存在
获取/读取/遍历对象的属性主要有以下几种方式:
Object.keys(obj)
获取对象上全部自有的可枚举的字符串属性
自有:相对与原型属性,可以通过
obj.hasOwnProperty('a')
方法检查可枚举:可枚举的属性,其
enumerable
描述符为true
,可以通过Object.getOwnPropertyDescriptor(obj, 'a')
查看某个属性的描述符
for in
获取对象上全部可枚举的字符串属性(包括原型链上的可枚举属性),与 Object.keys 的区别就在于原型链上的可枚举属性也会被遍历出来
in
关键字
判断字符串属性是否在对象及对象的原型链上,即不会受到自有以及可枚举的限制
Object.getOwnPropertySymbols(obj)
获取对象上全部的 Symbol 属性
Reflect.ownKeys(obj)
返回对象的所有自有属性
判断对象是否为空
常用方法:
- JSON 序列化:
JSON.stringify(obj) === '{}'
- But: 只能序列化字符串类型且可枚举的键,忽略 Symbol 等其他类型或不可枚举的键
- 遍历:
for in | Object.keys(obj).length === 0
- But: 同样,无法遍历不可枚举且非字符串的属性
更严谨的方法:
Reflect.ownKeys(obj).length === 0
Reflect
是 ES6(ECMAScript 2015)引入的一个内置的对象,它提供了拦截 JavaScript 操作的方法。
Reflect.ownKeys
方法用来返回一个由目标对象自身的所有键(包括字符串键、Symbol
键)组成的数组。这个方法实际上是在底层提供了一个更完整的方式来获取对象自身的所有属性名称(即使是不可枚举的属性)和 Symbol
键值。
因为它设计用来执行默认操作,而无论是字符串还是 Symbol
类型的键,都是对象自身属性的一部分。在语言规范中,对象属性的集合被视为属性的名字和它们对应的属性描述符的集合。Reflect.ownKeys
正是直接提供了这个集合的视图。
详见 Reflect 一文
- 过分一点的需求:确定对象的原型链上也没有属性
- 使用
Object.getPrototypeOf
function readPrototypeProperties(object) {
let proto = Object.getPrototypeOf(object);
while (proto) {
console.log(Object.getOwnPropertyNames(proto)); // 输出当前原型上的属性
proto = Object.getPrototypeOf(proto);
}
}
readPrototypeProperties(obj);
- 使用
__proto__
属性
let proto = obj.__proto__;
while (proto) {
console.log(Object.getOwnPropertyNames(proto)); // 输出当前原型上的属性
proto = proto.__proto__;
}