获取对象属性的几种方法

7,401 阅读3分钟

前言

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'这是字符串类型的不可枚举属性',
  writeabletrue,
  enumerablefalse,
  configurabletrue
})
Object.defineProperty(obj, Symbol('unenum'), {
    value'这是Symbol类型的不可枚举属性',
    writeabletrue,
    enumerablefalse,
    configurabletrue
})

// 在 obj 原型上定义一个属性
obj.__proto__.bbb = '这是obj原型上的属性'

我们试着用 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