js对象的属性有很多种,总结这一篇文章是为将来理解对象复制和对象继承打基础。
数据描述符
1. 可枚举性(Enumerable)
实际上对象的每一个属性都有一个标志位,表示这个属性是否可以枚举。我们通过obj.a=123
这种方式设置的属性都为可枚举属性。有时候我们需要将属性设置为不可枚举,因为我们不希望这个属性在迭代的时候被访问(for...in
或 Object.keys
方法)。
原生对象中几乎所有属性都是不可枚举的。
你可以通过obj.propertyIsEnumerable(prop)来判断自身属性是否可枚举。
2. 可配置性(configurable)
当且仅当该属性的 configurable 为 true 时,该属性描述符
才能够被改变,也能够被删除。我们通过obj.a=123
这种方式设置的属性都为可配置属性。
3. 可写性(writable)
当且仅当该属性的 writable 为 true 时,该属性才能被
赋值运算符改变。我们通过obj.a=123
这种方式设置的属性都为可写属性。
存取描述符
get方法
一个给属性提供 getter 的方法,它决定了你访问这个属性的时候会发生什么。
set方法
一个给属性提供 setter 的方法,它决定了你给这个属性赋值的时候会发生什么。
数据描述符和存取描述符可以通过Object.defineProperty(obj, prop, descriptor)来设置或修改。有关如何使用它们,也可以在这个方法的描述中看到。
是否是对象自身的属性
对于一个对象来说,它的某个属性要么属于对象自身,要么是在原型链上。
有关原型链的内容,可以看我的另一篇文章彻底理解js的原型链。
相关方法
判断方法:
- obj.propertyIsEnumerable(prop) 返回该属性是否可以枚举,如果不是自身的属性,直接返回false。
- obj.hasOwnProperty(prop):参数为属性名,返回布尔值,这个属性是否属于对象自身。只要在对象自身上,不管可不可枚举都返回true。
- in 操作符:用法
prop in objectName
,返回这个属性是否存在于对象自身或原型链上,只要存在,不管可不可枚举都返回true。注意如果属性名是字符串,要用引号括起来。
获取方法:
- Object.getOwnPropertyDescriptor
- Object.getOwnPropertyNames(obj):返回obj的所有自身属性的属性名(包括可枚举和不可枚举的属性)组成的数组。
- Object.keys(obj):返回obj的所有可枚举的自身属性的属性名组成的数组。
- for (variable in object) {...}:迭代一个对象的所有可枚举属性,包括在原型链上的可枚举属性。
表格:
参考资料
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
- http://javascript.ruanyifeng.com/stdlib/attributes.html
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties