ES5(一)——保护对象

一、ES5之保护对象:

在ES5中,为对象提供了一套保护自身的机制
对象中的每个属性,不仅是一个简单的值,底层已经变成了一个缩微的小对象。

1.自带的三个保护属性

例如,value = “1”,底层包含以下三个常用属性,可看作三个开关:

属性作用
writable: true控制是否可修改当前属性值
enumerable: true控制是否可用for in遍历到这个属性
只防"for in",不防"."
configurable: true1.控制是否可删除当前属性
2.控制是否可修改前两个开关!
一旦改为false,不可逆!

2.修改属性的开关:

2.1 修改单个属性

只要修改writable和enumerable两个开关时,必须同时修改configurable:false,阻止别人的程序重新打开我们关闭的开关。

模板:

 Object.defineProperty(对象名, "属性名", {
        开关:truefalse,
        ... : ...
 })

示例:

var erya={
    eid:1,
    ename:"二雅",
    salary:1022
}
Object.defineProperty(erya, "eid",
    // eid禁止修改——只读
    { 
        writable:false,
        configurable:false //双保险
    }
})

2.2 修改多个属性

模板:

Object.defineProperties(对象名, {
  属性名1:{
    开关名: truefalse, 
    ... : ...
  },
  属性名2:{
    开关名: truefalse, 
    ... : ...
  },
})

示例:

var erya={
    eid:1,
    ename:"二雅",
    salary:1022
}
// 修改多个属性开关
Object.defineProperties(erya,{
    // ename禁止删除
    ename:{
      configurable:false
    },
    //salary禁止随意用for in循环遍历
    salary:{
      enumerable: false, //半隐藏
      configurable:false
    }
})

2.自定义规则-访问器属性

访问器属性定义:自己不保存属性值,只提供对另一个数据属性的保护——保镖

2.1 定义访问器属性

1) 定义小黑屋属性,转移原对象中原属性的值
Object.defineProperty(原对象,"小黑屋",{
  value:原对象.要保护的属性,
  writable:true,
  enumerable:false, //小黑屋不能轻易被人发现
  configurable:false //小黑屋不可删除
})
2) 定义访问器属性替身+2保镖(get_set)
Object.defineProperty(原对象,"要保护的原属性名",{

 //保镖一:获取外界的信息
get:function(){
  //this->访问器属性eage所在的当前对象->eric
  return this.小黑屋;
},

 //保镖二:将信息返回到外界
set:function(value){
  if(判断条件){
    this.小黑屋=value;
  }else{
    throw Error("自定义错误提示");//复习第一阶段try catch异常处理
  }
},

在这里插入图片描述

2.2 外界使用访问器属性

和使用对象的普通属性完全一样:
1) 取值: 对象.属性名
底层: 自动调用访问器属性的 get()

2) 修改: 对象.属性名=新值
底层: 自动调用访问器属性的 set(),将新值传给()中的value形参。

示例: 使用访问器属性保护年龄属性:

var erya={
    ename:"二雅",
    eage:20
}
//eage可修改,18~65

//1. 定义小黑屋属性,转移原对象中原eage属性值
Object.defineProperty(erya,"小黑屋",{
    value:erya.eage,
    writable:true,
    enumerable:false,
    configurable:false
})

//2. 定义访问器属性替身+2保镖
Object.defineProperty(erya,"eage",{
    //访问器属性自己不存值,只提供保护,所以没有value属性

    // 保镖一:
    get:function() {
        console.log(`eage自动调用了自己的get(),返回${this.小黑屋}给外部`)
        //this->访问器属性eage所在的当前对象->eric
        return this.小黑屋;
    },
    set:function(value) {
        console.log(`eage自动调用了自己的set(),接收外部传入的新值${value}`);
        if (value>=18&&value<=65) {
            this.小黑屋=value;
        } else {
            throw Error("年龄超范围!");
        }
    },
    
    //正是因为writable不好用,我们才被迫用访问器属性代替writable,所以用了get/set,就不用writable。
    //因为替身必须替真实属性抛头露面,所以,必须可以被for in发现
    enumerable:true,
    //因为替身不能随意删除
    configurable:false
})

//外界试图获得erya的eage值
console.log(erya.eage);
//外界试图修改erya的eage属性
erya.eage=26;
//外界试图获得erya的eage值
console.log(erya.eage);
//外界试图修改erya的eage属性
erya.eage=-2;//抛出异常

2.3 访问器中的this

访问器属性中的this->访问器属性所在的当前对象

3.保护结构

a. 防扩展

禁止给对象添加新属性

Object.preventExtensions(对象)

b. 密封

禁止添加新属性,又禁止删除现有属性

Object.seal(对象)

i. 会自动调用preventExtensions(),先禁止添加
ii. 会自动遍历对象中每个属性,自动设置每个属性的configurable:false,所有属性禁止删除。

tip:
1.用seal(),既不用写preventExtensions(),又不用写所有的configurable:false
2. seal()虽然不能添加删除属性,但可以修改属性值。
3. 一般,保护到密封级别就够了!

c.冰冻

既禁止添加删除属性,又禁止修改一切属性值。

Object.freeze(对象)

i. 会自动调用preventExtensions(),先禁止添加
ii. 会自动遍历对象中每个属性,自动设置每个属性的configurable:false,所有属性禁止删除。
iii. 会自动遍历对象中每个属性,自动设置每个属性的writable:false,所有属性只读

示例:

var erya={
    eid:1,
    ename:"二雅",
    salary:1022
}
Object.defineProperties(erya, {
    eid:{ writable:false },
    salary:{ enumerable:false }
})

//防扩展: 
Object.preventExtensions(erya);

//密封: (够了)
Object.seal(erya);

//冻结: (过于严格)
Object.freeze(erya);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你脸上有BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值