Object.defineProperty

1、基本用法

Object.defineProperty方法用于在对象上定义一个新属性,或者修改对象现有属性,并返回此对象。

Object.defineProperty(obj, prop, descriptor)

  • obj是我们要添加、修改属性的对象
  • prop是我们要操作的属性名
  • descriptor是我们操作属性的具体描述

2、descriptor中的数据描述符

Object.defineProperty方法中的descriptor属性繁多,所以它也非常强大,我们之前说的数据劫持,数据是否可写,是否可删除,是否可枚举都在这个descriptor中定义。在介绍每个属性前,我们还得引入一个新概念,即:

对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一,不能同时是两者。

2.1、writable是一个布尔值,若不定义默认为false,表示此条属性只可读,不可修改

如果严格模式下,修改writable属性为false的对象属性会报错。

 

 扩展:关于const声明的变量是否可以修改

如果我们const声明变量赋值是基本类型,只要修改值一定报错;如果值是引用类型,比如值是一个数组,当我们直接使用赋值运算符整个替换数组还是会报错,但如果我们不是整个替换数组而是修改数组中某个元素可以发现并不会报错。

 

 这是因为对于引用数据类型而言,变量保存的是数据存放的引用地址,比如b的例子,原本指向是[1]的地址,后面直接要把地址改成数组[1,2]的地址,这很明显是不允许的,所以报错了。但在c的例子中,我们只是把c地址指向的数组中的一位元素改变了,并未修改地址,这对于const是允许的。这个特性对于writable也是适用的。

 2.2、getter和setter

通常情况下,我们为对象赋予什么值,就会取得什么值:

 如果我们要统计一个班级的成绩,输入60就返回及格,输入90返回优秀,这种情况就可以使用Object.defineProperty()中的存取描述符来解决这个需求,存取描述符给了我们赋值/取值时数据劫持的机会,也就就是在赋值与取值时能自定义做一些操作:

  • getter函数在获取属性值时触发,注意,是你为某个属性添加了getter在获取这个属性才会触发,如果未定义则为undefined,该函数的返回值将作为你访问的属性值。
  • setter函数在设置属性时触发,同理你得为这个属性提前定义这个方法才行,设置的值将作为参数传入到setter函数中,在这里我们可以加工数据,若未定义此方法默认也是undefined。

 2.3、configurable和enumerable

enumerable值类型为Boolean,表示该属性是否可被枚举,默认为false:

 configurable的值也是Boolean,默认是false,configurable 特性表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。

 

 当configurable为false时,其他属性不管有没有写出来(有默认值),都无法被重新定义或修改。

 

 对象属性描述符要么是数据描述符(value,writable),要么是存取描述符(get,set),不应该同时存在两者描述符:

  

 存取方法就是用来定义属性值的,value也是用来定义值的,同时定义程序也不知道该以哪个为准了,所以用了value/writable其一,就不能用get/set了;不过configurableenumerable这两个属性可以与上面两种属性任意搭配。

 2.4、默认值

   等同于   

   等同于    等同于  

 3、根据分数显示成绩

3.1、通过Object.defineProperty实现:

3.2、通过原型链实现

 3.3、通过ES6的class类实现

 

posted on 2021-01-05 08:41  紅葉  阅读(3793)  评论(0编辑  收藏  举报