Property Descriptor对象中存在的属性描述符有两种主要类型:数据描述符和访问器描述符。 数据描述符是一个具有可写或不可写值的属性。 访问器描述符是由 getter/setter 函数对描述的属性。 **一个描述符只能是这两者其中之一;不能同时是两者;**一起时会报错 默认为数据描述符
数据描述符和访问器描述符共享属性
- configurable:该属性的描述符本身是否可以修改
- enumerable:该属性是否可以被枚举
configable
configable设置为false时,
- 不可以在数据描述符和访问器描述符之间来回切换
- 不可以删除该对象属性
- 不可以更改其他的数据描述符(
writable为true时,value还****是可以更改)
注意:
configable设置为false时,不能再改为true
numerable
numerable设置为false时,该对象属性为 不可枚举 属性
目前,有四个操作会忽略enumerable为false的属性。
- for...in循环:只遍历 (对象自身的和继承的) 可枚举 的属性。
- Object.keys():返回(对象自身)的所有可枚举的属性的键名。
- JSON.stringify():只串行化(对象自身)的可枚举的属性。
- Object.assign(): 忽略
enumerable为false的属性,只拷贝(对象自身)的可枚举的属性。
for...in 会遍历自身及原型链 的属性(对象的
[[Prototype]])
冷知识:enumerable 设计之初,就是为了防止对象的某些属性被for in遍历出来,例如length,toString
数据描述符
- value:属性值
- writable:该属性的值是否可以被重新赋值
value(没啥好写的)
writable
writable 为false时,对象属性不可以赋值
访问器描述符
- get:获取函数
- set:存值函数
当用访问器描述符,然后将
set函数变成undefined,那该属性就会变成只读属性
API
关于对象属性的遍历
5 种方法可以遍历对象的属性
- for...in
- Object.keys
- Object.getOwnPropertyNames:返回 不含
Symbols的键名 - Object.getOwnPropertySymbols:返回
Symbols的键名 - Reflect.ownKeys:这个说一下,返回自身的所有键名(可枚举和不可枚举,
Symbols)
以上的遍历,遵守同个属性遍历的次序规则
- 先数值,数值升序
- 再字符串,插入时间升序
- 再
Symbol,插入时间升序
这里简单背一下 for...in:可枚举,原型链 Object.keys:可枚举 Object.assign:可枚举 JSON.stringify:可枚举 Object.getOwnPropertyNames:除了Symbol Object.getOwnPropertySymbols:Symbol Reflect.ownKeys:所有 再加一些API Object.hasOwnProperty Object.hasOwn
关于对象属性描述符
- Object.defineProperty(obj, prop, descriptor)
- Object.defineProperties(obj, {多个prop和descriptor})
- Object.getOwnPropertyDescriptor(obj, prop)
- Object.getOwnPropertyDescriptors(obj)
- Object.create(proto, descriptor)
我们再看看关于对象不可扩展,密封,冻结相关的API
对象(不可扩展,密封,冻结)相关的API
- Object.preventExtensions/Object.isExtensible
- Object.seal/Object.isSeal
- Object.freeze/Object.isFrozen
Object.preventExtensions
防止对象可扩展
Object.preventExtensions(obj)
该对象的自有属性(不包括继承)不可扩展,不可以添加新属性,不可以替换 [[prototype]]
Object.seal
密封一个对象(浅密封)
Object.seal(obj)
该对象被密封,等价于,该对象不可扩展(preventExtensions) + 该对象的所有属性的configurable:false
回想一下 configurable:false 的效果,
- 该属性描述符配置不可更改
- 该属性不可删除
- 不能在 数据描述符 和 访问器描述符 之间切换
所以再加一条,
- 不可以添加属性
Object.freeze
冻结一个对象(浅冻结)
Object.freeze(obj)
该对象被冻结,等价于,该对象被密封(seal) +该对象的所有属性的writable:false
再来背一下
- 该属性不可删除
- 该属性描述符不可修改
- 不能在 数据描述符 和 访问器描述符 之间切换
- 不可添加
- 不可修改(新)
暂时想的这么多