ES5_保护对象

本文探讨了JavaScript中对象属性的可操作性,包括如何通过设置属性的四大特性(value、writable、enumerable、configurable)来保护对象和属性。介绍了数据属性和访问器属性的区别,以及如何使用闭包和访问器属性来保护自定义属性。同时,讲解了对象保护的三个级别:防扩展、密封和冻结,并提供了构造函数示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JS对象中的普通属性随时可以被修改、添加新属性、也可以被随时删除。主要是因为对象的属性默认是可以操作的。
通过设置对象属性的可操作性,从而达到保护对象保护属性

保护属性

命名属性:即可以用 . 访问的属性;

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

属性的四大特征:

value:实际存储的属性值;
writable: 是否可修改 默认为true;
enumerable: 是否可被for in遍历到默认true。仅能控制for in,无法控制.的访问
configurable: 是否可修改其它特性 是否可删除该属性

获取四大特性:var attrs=Object.getOwnPropertyDescriptor(obj,"属性名");

设置属性:

Object.defineProperty(obj,"属性名",{
   特性:,
})
//问题: 一次只能修改一个属性的四大特性
//解决: 同时修改多个属性的四大特性?
Object.defineProperties(obj,{
     属性名:{ 特性:, ... },
      ... : ...
})

若修改的属性不存在,就会自动创建该属性。通过defineProperty添加的属性,四大特性默认都是false;通过对象直接添加的属性,四大特性默认值都是true

访问器属性不直接存储属性值,专门对其他属性提供保护的特殊属性,因为数据属性的四大特性无法使用自定义规则保护属性。

保护自定义属性,只要在使用时定义一个闭包结构,实际存储属性值,然后定义一个访问器属性来保护闭包中的局部变量即可,例如:

+function(){
    var 变量;
    Object.defineProperty(obj,"属性名",{
        get:function(){
            return变量;
        },
        set:function(val){
            变量=val;
        },
        enumerable:true/false,
        configurable:true/false
    })
}();
//自定义特性,设置访问器属性
//匿名函数自调
var eric={id:1001,ename:"Eric"};
+function(){
    var _age;
    Object.defineProperty(eric,"age",{
        get:function(){return _age;},//get(){},
        set:function(val){
            if(val>=18&&val<=65) _age=val;
            else throw new Error("年龄介于18~65之间")
        }
    })
}();
eric.age=20;
console.dir(eric);
console.log(eric.age);

受保护的数据不能保存在普通的数据属性中,因为数据属性可以随意被访问,通过设置内部属性,即不允许用.访问的属性,像class __proto__.

保护对象
三个级别:
1、防扩展: 禁止向对象中添加新属性

Object.preventExtensions(obj);

2、密封: 即防扩展,又禁止删除任何属性

Object.seal(obj);
//1、防扩展
//2、将所有属性的configurable都设置为false!

3、冻结: 即防扩展,又禁止删除,同时禁止修改一切属性值

Object.freeze(obj);
//1、防扩展
//2、将所有属性的configurable都设置为false!
//3、将所有属性的writable都设置为false
//最严谨的构造函数
function Emp(ename,id,salary,age){
    this.ename=ename;
    this.id=id;
    this.salary=salary;
    var _age;
    Object.defineProperties(this,{
        id:{writable:false},
        salary:{enumerable:false},
        age:{
            set(val){
                if(val>=18&&val<=65) _age=val;
                else throw new Error("年龄介于18~65之间")
            },
            get(){return _age},
            enumerable:true
//用.创建的新属性,通过defineProperty/defineProperties修改,默认值为true
//用defineProperty/defineProperties添加的新属性,特性的默认值为false
        }
    })
    this.age=age;
    //防扩展:(禁止添加新属性)(extensible:false)
   //设置当前新对象禁止扩展新属性
   //Object.preventExtensions(this);
    //密封,不可扩展,也不可删除(configurable:false)
    Object.seal(this);
    //冻结,密封且不可修改(wretable=false)
    //Object.freeze(this);
}
var Lisi=new Emp("lisi",101,10000,24);
var Hanmei=new Emp("hanmei",102,13000,26);
var Zhaoyun=new Emp("zhaoyun",103,18000,29);
//Zhaoyun.age=78;//错误
for(var key in Zhaoyun)console.log(Zhaoyun[key]);
console.dir(Lisi);
console.dir(Hanmei);
console.dir(Zhaoyun);

严格模式

比普通的js执行模式更严格的全新的执行模式 在每个js文件的开头:”use strict”; 让整个js文件启动严格模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值