【面向JS--ES5保护对象】

前言

你知道吗,对象的属性也是有属性的!

js中对象的普通属性,随时可别修改为任何值,随时可添加新属性,随时可被删除。

这是因为对象的属性默认是可操作的,而通过修改对象属性的属性,我们可以设置对象属性的可操作性。

我们设置的目的就是 保护对象保护属性

回顾Object.create():

基于一个父对象,创建一个子对象,并为子对象扩展新属性。
var son=Object.create(父对象,{
    扩展属性名1:{
        writable:true,//是否可修改,可以省略
        value:属性值,
        configurable:true//可以设置,可以省略
    },
    扩展属性名2:{...}
});

保护属性

属性分为:

命名属性: 可用.访问到的属性
数据属性: 直接存储属性值的属性

每个属性都有四大特性:

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

获取四大特性:

var attrs=Object.getOwnPropertyDescriptor(obj,"属性名");

设置四大特性:

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

问题: 如果要修改的属性不存在?

答: 会自动创建该属性: 
强调: 
通过defineProperty添加的属性,四大特性默认都为false!
通过对象直接量添加的属性,四大特性默认值都是true!

问题: 四大特性,只能对属性提供基本的保护,如何使用自定义规则保护属性

访问器属性: 不直接存储属性值,专门对其它属性提供保护的特殊属性
为什么: 数据属性的四大特性无法使用自定义规则保护属性
何时: 只要使用自定义规则保护属性时
如何: 2步:
1、定义一个闭包结构,实际存储属性值
2、定义一个访问器属性来保护闭包中的局部变量,如下:
+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);
2件事: 1、防扩展
      2、将所有属性的configurable都设置为false!

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

Object.freeze(obj);
3件事: 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文件,都要启用严格模式

如何:2种

1.新项目:在每个js文件的开头:”use strict”;  让整个js文件启动严格模式
2.旧项目:逐个函数启动
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值