zoukankan      html  css  js  c++  java
  • 初步认识对象中属性的类型(对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);

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

    对上述对象输出console.log(Object.getOwnPropertyDescriptors(book));
  • 相关阅读:
    高性能队列设计
    线上 RTT 有 1/3 概率超过 3 秒,我用 arthas 查出元凶!
    你管这破玩意儿叫 token
    高可用与Zookeeper设计原理
    从应用层到网络层排查 Dubbo 接口超时全记录
    我是如何晋升专家岗的
    百亿数据,毫秒级返回,如何设计?--浅谈实时索引构建之道
    微信的原创保护机制到底是如何实现的
    AOP面试造火箭始末
    与一位转行做滴滴司机的前程序员对话引发的思考
  • 原文地址:https://www.cnblogs.com/zxf906/p/14999895.html
Copyright © 2011-2022 走看看