# 获取对象属性的几种方法
# 前言
javascript 中对象的属性只支持 字符串
和 Symbol
两种类型 ,如果我们使用的是其他类型值作为属性名,最后都会被转为字符串。
不过在 es6 中新增了一种数据结构 Map
,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
关于 Map 以后再介绍,本篇文章介绍的是获取对象属性(键值)的方法有哪些 😎。
# Object.getOwnPropertyNames()
Object.getOwnPropertyNames() 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。
我们创建一个 obj 对象,里面包含了‘字符串属性’和‘Symbol 属性’,接着给对象添加两个不可枚举属性,然后再在它的原型上定义一个属性。
var str = 'aaa'
var number = 111
var symbol = Symbol(111)
var obj = {
[str]: '这是一个‘字符串’属性',
[number]: '这也是一个‘字符串’属性',
[symbol]: '这是一个‘Symbol’属性'
}
// 在 obj 定义一个不可枚举属性
Object.defineProperty(obj, 'unenum', {
value: '这是字符串类型的不可枚举属性',
writeable: true,
enumerable: false,
configurable: true
})
Object.defineProperty(obj, Symbol('unenum'), {
value: '这是Symbol类型的不可枚举属性',
writeable: true,
enumerable: false,
configurable: true
})
// 在 obj 原型上定义一个属性
obj.__proto__.bbb = '这是obj原型上的属性'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
我们试着用 Object.getOwnPropertyNames() 方法看看会返回什么。
可以看到只返回了所有自身属性的键值(不包括 Symbol 类型)。
# Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性(包括不可枚举的)的数组。
用上面的代码试一下这个方法
可以看到返回的是自身所有 Symbol 类型的属性。
# for in
for...in 语句以任意顺序遍历一个对象的除 Symbol 以外的可枚举属性。是否属于可枚举属性我们可以通过对象的 propertyIsEnumerable('property')方法来查看。
来试一下 for...in
可以看到返回了对象自身及所在原型链上的所有可枚举字符串属性(不包括 Symbol 类型)。
# Object.keys()
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
再来试一下 Object.keys()
可以看到只返回了自身的可枚举属性(不包括 Symbol 类型和原型上的)。
相当于 for...in 和 hasOwnProperty()结合。
# Reflect.ownKeys
Reflect.ownKeys 方法返回一个由目标对象自身的属性键组成的数组。它的返回值等同于 Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj))。
最后试一下 Reflect.ownKeys
可以看到返回了自身所有属性(包括 Symbol 类型,但不包括原型上的属性)。
# 总结
实际开发中可能会将几种方法组合起来使用。为了方便记忆,将各种方法的特性写在一张表格里。
方法 | 能否返回不可枚举属性 | 能否返回 Symbol 属性 | 能否返回原型上的属性 |
---|---|---|---|
Object.getOwnPropertyNames() | 是 | 否 | 否 |
Object.getOwnPropertySymbols() | 是 | 是 | 否 |
for...in | 否 | 否 | 是 |
Object.keys() | 否 | 否 | 否 |
Reflect.ownKeys | 是 | 是 | 否 |
在线客服