如果在开发中我不想让别人对obj对象添加或删除元素 可以砸子做?
当该属性的
configurable键值为true时该属性的描述才能被修改 同时该属性也能从对应的对象上被删除
就是说如果configurable值为false时属性就无法从对象上面删除 这个方法 仅能使对象内的 元素无法被删除 依旧可以在新对象中添加新的对象
看代码示例
Object.defineProperty(obj,"prop",{
configurable:false, //configurable属性为true时 该属性的秒速符才能被修改 同时该属性也能从对应的对象上被删除
enumerable:false, //enumerable 属性为true时 该属性才会出现在对象的枚举属性中
writable:false, //表示 是否可以修改属性的值
value:"" //该属性的值 可以是任何有效的js 值(数值,对象,函数)
})
//这样设置以后 prop属性就变成了不能删除 不能重新修改特性 不可枚举 不能修改的属性值的属性
// 示例代码
const obj = {name:"东东"}
Object.defineProperty(obj,"name",{
writable:false,
configurable:false
})
// 修改
obj.name = "收购腾讯";
console.log(obj.name); //东东
// 添加新的属性
obj.address = "青岛"
console.log(obj.address); //青岛
Object.freeze(person);
冻结的对象既不可扩展,又是密封的,而且对象,数据属性的[ [Writable] ]特性会被设置为false。
如果定义[ [Set] ]函数,访问器属性仍然是可写的。ES5定义的Object. freeze()方法可以用来冻结对象。 代码所示
var person = {
name: "大黄"
};
Object.freeze(person); //冻结了这个对象
person.age = 18; //新添加一个age属性 没有起效果
console.log(person.age); //undefined
delete person.name; //删去name属性 没有起效果
console.log(person.name); //"大黄"
person.name = "咪咪"; //改变已有的属性 没起到效果
console.log(person.name); //"大黄"
// Object. isFrozen()方法用于检测冻结对象。因为冻结对象既是密封的又是不可扩展的,
// 所以用Object.isExtensible()和Object.isSealed ()检测冻结对象将分别返回false和true。
var person = {
name: "老王"
};
alert(Object.isExtensible(person)); //true
alert(Object.isSealed(person)); //false
alert(Object.isFrozen(person)); //false
Object.freeze(person);
alert(Object.isExtensible(person)); //false
alert(Object.isSealed(person)); //true
alert(Object.isFrozen(person)); //true
Object.seal()
这个方法封闭(密封)一个对象 阻止添加新属性 并将所有的属性标记为不可配置
当前属性的值 只要原来的可写的 就可以改变
一个对象是可拓展的(可以添加新的属性)
1密封一个对象会让这个对象变得不能添加新属性
且所有已有的属性会变得 不可配置(属性不可配置的效果 即属性不可删除)
2以及一个数据属性 不能被重新定义成为访问器属性 或者反之
但属性的值仍然可以修改
3尝试删除一个密封对象的属性或者
将某个密封对象的属性从数据属性 转换为访问器属性 结果会静默抛出TypeError
看示例代码
var person = {
name: "收购百度"
}
Object.seal(person); //封闭这个对象
person.age = 19;
console.log(person.age); //undefined
//无法给密封对象添加属性
delete person.name;
console.log(person.name);//收购百度
//无法修改密封对象中的属性。
//使用Object.isSealed() 方法确定对象是否被密封 而且由于被密封的对象不可扩展,
//所以Object.isExtensible() 检测也会返回 false。
var person = {
name: "老王"
}
Object.seal(person);
console.log(Object.isSealed(person)); //true
console.log(Object.isExtensible(person)); //false
es5的防止篡改对象
但是要注意,一旦把对象定义为防篡改对象,就无法撤销了。
默认情况下,所有对象都是可以扩展的。也就是说,任何时候都可以向对象中添加属性和方法
//Object.preventExtensions() 方法
//1 改变这一行为 不能再添加属性或者方法。
//2 虽然不能扩展该对象,但是不影响原有的属性,原有的属性仍然可以进行修改或者删除。
var person = {
name: "收购腾讯"
}
Object.preventExtensions(person); //将person设置为不可扩展对象
person.money = 14;
console.log(person); //{name: "收购腾讯"}
console.log(person.money); //undefined
person.name = "收购阿里 ";
console.log(person.name); //收购阿里
//使用 Object.isExtensible() 方法可以确定该对象是否为可扩展对象。
var p = {
name: "老王"
}
console.log(Object.isExtensible(p)); //ture
Object.preventExtensions(p); //将p设置为不可扩展对象
console.log(Object.isExtensible(p)); //false
es6 常量冻结
//常量冻结
const esObj = { //这里是一个对象
name:"es6",
year:2015
}
//Object.freeze(esObj); //加上这一句 则下面的log{name:"es6",year:2015}
esObj.name ="es2015";
console.log(esObj) //{name:"es2015", year:2015}
const arr = ['es6','es7','es8']; //这是一个数组
//Object.freeze(arr) //冻结
arr[0] = 'es2015'
console.log(arr) //["es2015","es7","es8"]
/*
上面的代码说明 对象和数组 这类引用数据类型 因为在栈内存中存的引用地址 所以其堆内存中的内容是会被改变的
若不想被改变 加 freeze()方法冻结
*/
const esObj ={
name:"es6",
year:'2015',
extension:["es7","es8","es9"]
}
Object.freeze(esObj);
esObj.extension[0] = "es2016"
console.log(esObj)
/*
{name: "es6", year: "2015", extension: Array(3)}
extension: Array(3)
0: "es2016"
1: "es8"
2: "es9"
*/
//说明freeze的冻结只是 浅层次的 内部的数组还是会改变 这!!!
//看下面封装一下函数 定义一个myFreeze
function myFreeze(obj){
Object.freeze(obj);
Object.keys(Obj).forEach(function(key){ //Object.keys()方法会返回一个当前对象属性所组成的数组
if(typeof obj[key] === "object"){ //如果key对应的属性的值是一个对象的话
myFreeze(obj[key]) //那么再次冻结 递归 再次执行
}
})
}
//方法2
function meFreeze(obj){
//判断参数是否为object
if(obj instanceof Object){
for(let key in obj){
if(obj.hasOwnProperty(key)){
Object.defineProperty(obj,key,{
writable:false, //只读属性
})
Object.seal(obj) //封闭对象
}
}
}
return obj
}
注意:在对防篡改对象或者冻结对象时,在非严格模式和严格模式下,抛出的结果不一样 如果有错误或者不严谨的地方,请留言备注,十分感谢,对作者也是一种鼓励。