• ES中保护对象的措施总结


    必要性:  JS中的对象可随意修改属性值,可随意添加删除属性,太乱,数据安全得不到保障。

    如何保护:

        保护属性: 保护对属性值的修改

          对象属性分为:

            命名属性: 可直接用.访问到的属性

              数据属性: 直接存储属性值的属性

                如何保护: 四大特性:

                  value: 实际存储属性值

                  writable: 控制属性是否可修改

                  enumerable: 控制属性是否可被遍历

                   仅控制遍历,无法控制用.访问

                  configurable: 控制是否可删除属性

                           控制是否可修改其他两个特性

                强调: configurable经常作为前两个属性的双保险,且一旦设为false,不可逆!

                如果查看四大特性:

      

     Object.getOwnPropertyDescriptor(obj,"属性名")

                如何修改四大特性:

                  Object.defineProperty(obj,"属性名",{

                     特性:值,

                     特性:值,

                        ... ...

    })

    问题: defineProperty一次只能修改一个属性

    解决: 同时修改多个属性:

    Object.defineProperties(obj,{

         属性名:{ 要修改的特性 },

      属性名:{ 要修改的特性 },

          ... : ...

    })

              问题: 无法使用自定义逻辑保护属性

     解决:

              访问器属性: 不直接存储属性值

                         仅提供对其他数据属性的保护

              何时: 只要用自定义逻辑保护属性时

              如何: 2步:

                1. 定义一个隐藏的数据属性实际存储属性值

                2. 添加访问器属性保护隐藏的数据属性:

                  Object.defineProperty(obj,"属性名",{

                   get(){//在试图获取属性值时自动调用

                    //返回受保护的数据属性值

    },

    set(val){//在试图修改属性值时自动调用

     //参数val会自动获得要修改的新值

     //如果验证val符合规则

                       //才将val赋值给受保护的属性

     //否则

        //报错!

    },

    enumerable:true,

    configurable:false

    })

            如何使用访问器属性: 同普通属性用法完全一致

              其中赋值时,自动调用set,取值时自动调get

            内部属性: 不能用.直接访问的隐藏属性

               __proto__

        防篡改: 保护对对象结构的修改

          3个级别:

          1. 防扩展: 禁止添加新属性

            Object.preventExtensions(obj)

            原理: 每个obj内部都有一个隐藏属性:

                 Extensible,默认为true

            preventExtensions将obj的Extensible改为false

          2. 密封: 在防扩展基础上,进一步禁止删除现有属性

            Object.seal(obj)

            原理: 修改obj的Extensible为false

                  将所有属性的configurable都改为false

          3. 冻结: 在密封基础上禁止修改任何值

            Object.freeze(obj)

            原理: 修改obj的Extensible为false

                  将所有属性的configurable都改为false

                  还将所有属性的writable都改为false

    Object.create(): 可直接用一个父对象创建一个子对象。

      如何: var child=Object.create(father,{

             自有属性:{

               value:值,

               writable:true,

               enumerable:true,

               configurable:true,

    },

    ... : {

      ...

    }

    });

      强调: 只要添加到对象中的属性,四大特性默认为false,必须显式写为true。

      

    例子:

     "use strict";
    
      var emp={
        id:1001,     //禁止修改
        ename:"eric",//禁止删除
        salary:12000 //禁止遍历
      }
      //禁止修改id的值
      //禁止删除ename:
      //禁止遍历salary:
      Object.defineProperties(emp,{
        id:{
          writable:false,
          configurable:false
        },
        ename:{configurable:false},
        salary:{
          enumerable:false,
          configurable:false
        }
      });
    //  Object.defineProperty(emp,"id",{
    //    writable:false,
    //    configurable:false//不可逆
    //  });
    //  Object.defineProperty(emp,"ename",{
    //    configurable:false//不可逆
    //  });
    //  Object.defineProperty(emp,"salary",{
    //    enumerable:false,
    //    configurable:false//不可逆
    //  });
    
    
    //  Object.defineProperty(emp,"id",{
    //    writable:true,
    //    configurable:true
    //  });
    //  emp.id=1002;
    
    //  delete emp.ename;
      console.dir(emp);
      for(var key in emp){
        console.log(key+":"+emp[key]);
      }
      console.log(emp.salary);
      console.log(
        Object.getOwnPropertyDescriptor(
          emp,"id"//ename//salary
        )
      );
    "use strict";
      var config={
        IP:"192.168.0.100",
        PORT:27017,
        USER:"admin",
        PWD:"123456"
      }
      Object.freeze(config);
      //config.PORT=8080;
      delete config.PORT;
    var emp={id:1001,ename:"eric",_age:23};
      Object.defineProperty(emp,"_age",{
        enumerable:false,
        configurable:false
      });
      //要求:age必须介于18~65之间
      Object.defineProperty(emp,"age",{
        get(){
          console.log("自动调用get");
          return this._age
        },
        set(val){
          console.log("自动调用set");
          if(val>=18&&val<=65)
            this._age=val;
          else
            throw new RangeError("年龄必须介于18~65之间")
        },
        enumerable:true,
        configurable:false
      });
      //访问器属性的用法和普通属性完全一致
      emp.age++;
      console.dir(emp);
      emp.age=-2;
      var father={
        bal:10000000000,
        car:"infiniti"
      }
      var hmm=Object.create(father,{
        phone:{
          value:"IPhone 8 Plus",
          writable:true,
          enumerable:true,
          configurable:true
        },
        bao:{
          value:"LV",
          writable:true,
          enumerable:true,
          configurable:true
        }
      });
      console.dir(hmm);
  • 相关阅读:
    css浏览器兼容问题集锦
    【转】H264编码原理以及I帧B帧P帧
    Makefile Shell 脚本;sed命令
    oProfile 学习
    C++ 局部变量的析构
    【转】C++ 单例模式
    C++ operator 知识点 2
    C++ operator 知识点
    218多校第九场 HDU 6424 (数学)
    2018多校第九场 HDU 6416 (DP+前缀和优化)
  • 原文地址:https://www.cnblogs.com/web-fusheng/p/6764119.html
Copyright © 2020-2023  润新知