Object方法属性描述对象

1、属性描述对象概念
JavaScript 提供了一个内部数据结构,用来描述对象属性,控制它的行为。这个内部数据结构就称为属性描述对象。每个属性都有自己对应的属性描述对象,保存该属性的一些原信息。

{
    
    
	value:'111',//默认是undefined
	writable:true, //值为true或false  value值是否可改变
	enumberable:true, //  该属性是否可遍历 设置false则执行for...in循环或者Object.keys则会跳过该属性值
	configurable:true,//是否可配置修改这些元属性(即 writable/enumberable/configurable)
	get:undefined,//是一个函数 ,表示该属性的取值函数getter,默认为undefined
	set:undefined,//是一个函数,表示该属性的存值函数getter,默认为undifined	
}

2、常用的四个获取属性的函数
1、Object.getOwnPropertyDescriptor() 和Object.getOwnPropertyDescriptors() 获取对象的属性描述对象
在这里插入图片描述
都是获取对象的属性描述对象,使用语法如下:

 Object.getOwnPropertyDescriptors(Array)
 Object.getOwnPropertyDescriptor(Array,key)

2、Obect.getOwnPropertyNames() 返回的是一个对象中所有属性名的数组,不管属性是否可遍历

在这里插入图片描述
3、Object.defineProperty()(修改一个属性)和Object.defineProperties(修改多个属性)
该函数允许通过属性描述对象定义或者修改一个或者多个属性并且返回修改后的对象
Object.defineProperty()用法示例
在这里插入图片描述
Object.defineProperties()用法示例
在这里插入图片描述
4、Object.prototype.propertylsEnumberable() 返回一个布尔值,用来判断某个属性是否可以遍历
使用示例
在这里插入图片描述
注意使用时语法

array.propertyIsEnumerable('+key+')

5、元属性变化

  • writable 在false情况下赋值,赋值不成功,正常情况下不会报错,但严格模式下会报错,即使再赋回原来的值。同时子对象无法自定义它的值
    注:如果子对象想重新可以赋值可以重新对子对象重新覆盖赋值writable 属性
  • enumerable 在false的情况下 for…in / Object.keys() / JSON.stringify() 不会取到该属性(虽然循环不会取到,但是直接获取还是可以获取到的)
  • configurable 在false的情况下 改变value/wrtable/enumerable/configurable都会报错,但是在configurable由true改为false是允许的,直接赋值不会报错但是不会成功(如果configurable为true是该属性是可以被删除的,false则该属性不能被删除)

6、存取器
属性值除了直接定义外还可以使用存取器( accesser)定义。存值函数称为setter ,使用属性描述的setter值,取值函数称为getter ,使用属性描述的getter值
一旦定义了存取器则只要存取都将执行对应的setter/getter函数,可用于设置许多高级特性,比如某个属性禁止复制
用法示例
在这里插入图片描述
注意:设置set和get函数后则不能同时定义value值
存取器的另一种写法
在这里插入图片描述
存取器往往用于,属性的值依赖对象内部数据的场合。
7、控制对象状态的三种冻结方法
1、Object.preventExtensions() 使得一个对象无法再添加新的属性
Object.isExtensible() 检查对象是否用了这个方法。
2、Object.seal(), 使一个对象既无法再添加新的属性也无法删除旧的属性 该方法不影响修改某个属性的值 。可使用Object.isSealed()检查一个对象是否使用了Object.seal()
3、Object.freeze() 。无法添加新的属性,无法删除旧的属性,无法修改属性值 ,使之变成了常量 Object.isFrozen() 可检查是否使用了Object.freeze()
以上三种方法的局限性
可以通过改变原型对象,来为对象增加属性 例

var obj = new Object();
Object.preventExtensions(obj);

var proto = Object.getPrototypeOf(obj);
proto.t = 'hello';
obj.t
// hello

这时可以通过冻结obj的原型,如下

var obj = new Object();
Object.preventExtensions(obj);

var proto = Object.getPrototypeOf(obj);
proto.t = 'hello';
obj.t
// hello

还有一个局限,以上的方法冻结的属性指向的对象,但是不能冻结对象本身的内容,如下示例:

var obj = {
    
    
  foo: 1,
  bar: ['a', 'b']
};
Object.freeze(obj);

obj.bar.push('c');
obj.bar // ["a", "b", "c"]

猜你喜欢

转载自blog.csdn.net/qq_40969782/article/details/115310204