JS中的保护对象
保护数据属性:
ES5将每个数据属性,都变成一个缩微的小对象:
{ //四大特性:
value: //实际存储属性值
writable: true/false, //控制是否可修改
enumerable: true/false, //控制是否可被for in遍历
//但是,用.依然可强行访问该属性
configurable: true/false, //控制是否可删除该属性
//控制是否可修改另外两个特性
}
获取四大特性:
var attrs=Object.getOwnPropertyDescriptor(obj,"属性名");
设置四大特性:
Object.defineProperty(obj,"属性名",{
特性: 值,
})
问题: 一次只能修改一个属性的四大特性
解决: 同时修改多个属性的四大特性?
Object.defineProperties(obj,{
属性名:{ 特性: 值, ... },
... : ...
})
严格模式
比普通的js执行模式更严格的全新的执行模式
何时:几乎所有新项目的js文件,都要启用严格模式
如何:2种
- 新项目:在每个js文件的开头:”use strict”; 让整个js文件启动严格模式
- 旧项目:逐个函数启动
保护数据属性的两种方法:
1.修改单条数据的属性
Object.defineProperty
"use strict"; // 开启浏览器严格模式
var eric={
eid:1001, //只读
ename:"埃里克", //禁止删除
salary: 12000 //禁止遍历
}
//eid只读
Object.defineProperty(eric,"eid",{
writable:false,
configurable:false
})
//禁止删除ename?
Object.defineProperty(eric,"ename",{
configurable:false
})
//禁止for in遍历salary属性
Object.defineProperty(eric,"salary",{
enumerable:false,
configurable:false
})
//尝试重新打开writable和configurable开关
// Object.defineProperty(eric,"eid",{
// writable:true,
// configurable:true
// })
//尝试修改只读属性
//eric.eid=1002;
//尝试删除ename属性
//delete eric.ename;
console.log(eric);
for(var key in eric){
console.log(`${key} : ${eric[key]}`)
}
console.log(eric.salary);
2.同时修改多条数据属性
Object.defineProperties
"use strict"
var eric = {
eid: 1001,
// 不希望被修改,删除,遍历
ename: "埃里克",
// 不希望被删除
salary: 12000
// 不希望被遍历
}
Object.defineProperties(eric, {
eid: {
writable: false,
// 可修改
enumerable: false,
// 可遍历
configurable: false
// 是否能修改其他属性,如果改为false则不能再次修改
},
ename: {
configurable: false
// 是否能修改其他属性,如果改为false则不能再次修改
},
salary: {
enumerable: false,
// 可遍历
configurable: false
// 是否能修改其他属性,如果改为false则不能再次修改
}
})
console.log(eric)
// eric.eid = 1002
// delete eric.ename;
for (var i in eric)
console.log(i, eric[i])
保护访问器属性
保护访问器属性是用另一种方法,通过新建一个替身来保护访问器属性
"use strict"
var eric = {
ename: "埃里克"
}
Object.defineProperties(eric, {
//受保护的数据属性
_eage: { //半隐藏的本体
value: 25, //要求,年龄必须介于18~65之间
writable: true,
enumerable: false, //半隐藏
configurable: false
},
//请替身
eage: { //替身
get: function () {
console.log(`自动调用了eage的get(),从_eage中返回${this._eage}`);
return this._eage;
},
set: function (newValue) {
if (newValue >= 18 && newValue <= 65) {
this._eage = newValue;
} else {
throw Error("年龄必须介于18~65之间")
}
},
enumerable: true, //替身要替受保护的属性抛头露面
configurable: false //替身不允许删除!
}
})
//外人:
//尝试输出eric的年龄:
console.log(eric.eage);
//尝试修改eric的年龄为26
eric.eage = 26;
//尝试输出eric的年龄:
console.log(eric);
//尝试修改eric的年龄为-2
//eric.eage=-2; //报错
eric._eage = -2; //不能直接修改本体
console.log(eric);
保护对象属性结构
"use strict"
var eric = {
eid: 1001,
ename: "埃里克"
}
Object.preventExtensions(eric) //保护不被增加新属性
Object.seal(eric) //保护所有属性不被增,删
Object.freeze(eric) //保护所以属性不能被增删改
eric.eid = 1002
delete eric.ename
console.log(eric)