初步认识对象中属性的类型(对set set getter setter的认识)

JavaScript中对象的属性分为俩种:数据属性、访问器属性。

1.数据属性

数据属性包括四个特性(可称为属性描述符)

  • Value:数据属性才有的专门读写属性值的位置,默认值为undefined
  • Writable:表示属性的值是否可以被修改,默认为true
  • enumberable:表示属性是否可以被遍历(通过for-in循环返回),默认值为true
  • Configurable:表示属性是否可以配置(delete删除并重新定义、修改特性、改为访问器属性),默认为true

  给一个对象显示的添加属性后,value设置为属性指定的值,其余三个属性描述符默认为true

  object.defineProperty()是JavaScript提供用来修改属性默认特性的方法,它接受三个参数(object,'属性名','描述特性的对象')其中描述特性的对象可以包含以上四个任意特性的一个或多个,示例如下:

1  let person = {};
2             Object.defineProperty(person, "name", {
3                 value: "郑大侠", //设置person对象的name属性的值为'郑大侠'
4                 writable: false, //设置name属性的值不可修改
5             });
6             console.log(person.name); //郑大侠
7             person.name = "zxf";
8             console.log(person.name); //郑大侠
  • 值得注意的是configurable若设置为false,则该属性不能从对象上删除了,非严格模式下调用delete无效,严格模式下则会出错。此外,若属性的configurable特性设置为不可配置后,则不能再变回了,此后,除writable外,其余特性被修改都会报错。
  • 调用object.defineProperty()时,configurable,enumberable,writable的值如果没有设置,则都默认设置为false.

  2.访问器属性

  访问器属性比较特殊,不包括数据值,但包含获取函数getter和设置函数setter,这俩个函数不是必须的。

  每当读取访问器属性时,就会调用(触发)获取函数getter,其作用就是返回一个有效的值;

  在写入访问器属性时则会调用(触发)设置函数setter,这个函数决定对数据做出什么样的修改。

  访问器属性同样包括四个属性描述符:

  • configurable:表示属性是否可以配置(delete删除并重新定义、修改特性、改为数据属性),默认为true
  • enumberable:表示属性是否可以被遍历(通过for-in循环返回),默认值为true
  • get:获取函数,在读取属性时调用,默认值为undefined
  • set:设置函数,在写入属性时调用,默认值为undefined 

  与数据属性不同,访问器属性开发时并不常用,是不能直接定义的,必须使用Object.defineProperty() 

   

 1  // 定义一个对象并赋予俩个数据属性
 2             let book = {
 3                 year_: 2017,
 4                 edition: 1,
 5             };
 6 
 7             // 给book对象定义一个访问器属性:newYear
 8             Object.defineProperty(book, "newYear", {
 9                 get: function (newValue) {
10                     return this.year_;
11                 },
12                 set: function (newValue) {
13                     if (newValue > 2017) {
14                         this.year_ = newValue;
15                         this.edition += newValue - 2017;
16                     }
17                 },
18             });
19             book.newYear = 2021; //写入访问器属性时调用set函数使得book.year_ = 2021,book.edition = 5
20             console.log(book.edition); //5

以上是访问器属性典型的使用场景:设置一个属性值会导致一些其他变化的发生。我想,这便是Vue实现双向绑定以及响应式原理追踪数据变化的实现手段来源。通过object.defineProperty() 方法和访问器属性。

ps:另外我学到这里,有时看到getter与setter函数 ,到处找不到它们的定义,暂时将其理解为get:function(){}中具体的function(),get指向getter函数;setter同理。以后不对再来改

 

 

定义多个属性的方法Object.defineProperties():Object.defineProperties(要为其添加或修改属性的对象,{属性与其描述符的对象})如下:

 

 1               let book = {};
 2             // 一次性定义多个属性以及其属性描述符
 3             Object.defineProperties(book, {
 4                 name: { value: "雪中悍刀行" },
 5                 year_: { value: 2011 },
 6                 edition: { value: 1 },
 7                 newYear: {
 8                     get() {
 9                         return this.year_;
10                     },
11                     set(newValue) {
12                         if (newValue > 2011) {
13                             this.year_ = newValue;
14                             this.edition += newValue - 2011;
15                         }
16                     },
17                 },
18             }); //第二个参数为属性与其描述符组成的对象。        

 

 

 

另有读取属性的属性描述符(特性)的方法Object.getOwnPropertyDescriptor():接受俩个参数:属性所在的对象、要取得的其描述符的属性。返回值是一个对象。

对于普通数据属性返回Value,Writable,enumberable ,configurable四个属性描述符组成的对象;  

对于访问器属性返回configurable,enumberable,get,set四个属性描述符组成的对象。

 1  let book = {};
 2             // 一次性定义多个属性以及其属性描述符
 3             Object.defineProperties(book, {
 4                 name: { value: "雪中悍刀行" },
 5                 year_: { value: 2011 },
 6                 edition: { value: 1 },
 7                 newYear: {
 8                     get() {
 9                         return this.year_;
10                     },
11                     set(newValue) {
12                         if (newValue > 2011) {
13                             this.year_ = newValue;
14                             this.edition += newValue - 2011;
15                         }
16                     },
17                 },
18             });
19             let descriptor_year_ = Object.getOwnPropertyDescriptor(book,"year_");//descriptor_year_接收数据属性year_的描述符对象
20             console.log(descriptor_year_);
21             let descriptor_newYear = Object.getOwnPropertyDescriptor(book,"newYear");//descriptor_newYear接受访问器属性newYear的描述符对象
22             console.log(descriptor_newYear);

初步认识对象中属性的类型(对set set getter setter的认识)

另有Object.getOwnPropertyDescriptors()方法,只接受一个对象 ,它会分别获得该对象所有属性的所有属性描述符,并返回一个对象,该对象由其中每个属性与其属性描述符对象共同组成。

对上述对象输出console.log(Object.getOwnPropertyDescriptors(book)); 初步认识对象中属性的类型(对set set getter setter的认识)

 

 

 

上一篇:vue双向数据绑定原理


下一篇:实现一个 mini-vue