对象的属性有两种类型:字符串和 Symbol。javascript
var sybProp = Symbol()
var strProp = 'str'
var objProp = {}
var obj = {
[sybProp]: 'This is a String property',
[strProp]: 'This is a Symbol property',
[objProp]: 'This is also a String property'
}
obj
// {
// str: "This is a String property",
// [object Object]: "This is also a String property",
// Symbol(): "This is a Symbol property"
// }
复制代码
由于对象只支持字符串和 Symbol 两种类型的属性,若是咱们使用的是任何其余类型值做为属性名,最后都会被转为字符串。好比这里的 [objProp]
,objProp
是个对象,用它建立完 obj
后,再看看,就变成字符串 "[object Object]"
了。java
为了更好的演示,咱们先来定义一个操做对象。数据结构
var obj = {
str: 'This is a String property',
[Symbol()]: 'This is a Symbol property'
}
// 再定义一个不可枚举属性
Object.defineProperty(obj, 'unenum', {
value: 'This is a non-enumerable property',
writeable: true,
enumerable: false,
configurable: true
})
Object.defineProperty(obj, Symbol('unenum'), {
value: 'This is a non-enumerable Symbol property',
writeable: true,
enumerable: false,
configurable: true
})
//
Object.setPrototypeOf(obj, { foo: 'bar', [Symbol('foo')]: 'bar' })
复制代码
这个对象覆盖了下面要说的不一样方法之间的区别。包括一个字符串属性和 Symbol 属性,同时还具备一个不可枚举字符串属性和 Symbol 属性。另外,还重置了原型对象,原型对象里包含了一个字符串属性和 Symbol 属性(都是可枚举的)。ui
下面展现了 obj
的数据结构。spa
这三个方法都是用来获取对象上的属性集合的。只不过,Object.keys
是用来获取属性名集合,Object.values
是用来获取属性值集合,Object.entries
则是用来获取属性键-值对集合的。code
Object.keys(obj) // ["str"]
Object.values(obj) // ["This is a String property"]
Object.entries(obj) // [ ["str", "This is a String property"] ]
复制代码
经过结果能够发现,除了返回结果的不一样以外,这三个属性有一个共同点:只处理 obj
自身的可枚举字符串属性。cdn
顾名思义,Object.getOwnPropertyNames(obj)
获取的是对象自身的属性集合。但具体是哪些属性呢?咱们看下:对象
Object.getOwnPropertyNames(obj) // ["str", "unenum"]
复制代码
由结果可知,返回了 obj
自身的全部字符串属性(包括不可枚举的),但不包括 Symbol 属性。blog
Object.getOwnPropertySymbols(obj)
是跟 Object.getOwnPropertyNames(obj)
相对应的,返回 obj
自身的全部 Symbol 属性(包括不可枚举的)。ip
Object.getOwnPropertySymbols(obj) // [Symbol(), Symbol(unenum)]
复制代码
由结果可知,返回了 obj
自身的全部 Symbol 属性(包括不可枚举的),但不包括字符串属性。
Reflect.ownKeys(obj)
能够看作是 Object.getOwnPropertyNames(obj)
+ Object.getOwnPropertySymbols(obj)
,即得到 obj
自身的全部属性集合。
Reflect.ownKeys(obj) // ["str", "unenum", Symbol(), Symbol(unenum)]
复制代码
再来看看 for-in 语句遍历对象的结果为什么。
for (let prop in obj) {
console.log(prop) // "str" -> "foo"
}
复制代码
因而可知:for-in
返回的是对象自身及所在原型链上的全部可枚举字符串属性。
将 for-in 语句配合 obj.hasOwnProperty(prop)
方法一块儿使用,就能获得跟 Object.keys/values/entries
方法同样的效果——即返回对象自身的可枚举字符串属性。
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log({ key: prop, value: obj[prop], pair: [prop, obj[prop]] })
}
}
// {key: "str", value: "This is a String property", pair: ["str", "This is a String property"] }
复制代码
方法 | 返回值 | 备注 |
---|---|---|
Object.keys/values/entries |
对象自身的可枚举字符串属性 | |
Object.getOwnPropertyNames(obj) |
对象自身的全部可枚举、不可枚举的字符串属性 | |
Object.getOwnPropertySymbols(obj) |
对象自身的全部可枚举、不可枚举的 Symbol 属性 | |
Reflect.ownKeys(obj) |
对象自身的全部可枚举、不可枚举的字符串属性、Symbol 属性。 | 等同于 Object.getOwnPropertyNames(obj) + Object.getOwnPropertySymbols(obj) 的效果。 |
for (let prop in obj) {} |
对象自身及所在原型链上的全部可枚举字符串属性 |
(正文完)
广告时间(长期有效)
我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。
(完)