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文件启动严格模式