我们在开发中有时候会不经意的修改了别人的代码,可能会造成严重的后果,于是ES5定义了防篡改对象。但是要注意,一旦把对象定义为防篡改对象,就无法撤销了。

不可扩展对象

默认情况下,所有对象都是可以扩展的。也就是说,任何时候都可以向对象中添加属性和方法。比如:

1
2
3
4
5
6
var person = {
name: "阿清"
}
person.age = 14;
console.log(person);//{name: "阿清", age: 14}
console.log(person.age);//14

如果我们使用Object.preventExtensions() 方法可以改变这一行为。不能再添加属性或者方法。虽然不能扩展该对象,但是不影响原有的属性,原有的属性仍然可以进行修改或者删除。

1
2
3
4
5
6
7
8
9
10
11
12
var person = {
name: "阿清"
}

Object.preventExtensions(person); //将person设置为不可扩展对象

person.age = 14;
console.log(person); //{name: "阿清"}
console.log(person.age); //undefined

person.name = "阿广";
console.log(person.name);//阿广

使用 Object.isExtensible() 方法可以确定该对象是否为可扩展对象。

1
2
3
4
5
6
7
var person = {
name: "阿清"
}
console.log(Object.isExtensible(person)); //ture

Object.preventExtensions(person);
console.log(Object.isExtensible(person)); //false

密封对象

ECMAScript 5为对象定义的第二个保护级别是密封对象( sealed object)。密封对象不可扩展,而且已有成员的 [ [Configurable] ] 特性将被设置为false。这就意味着不能删除属性和方法,因为不能使用**Object.defineProperty ()**把数据属性修改为访问器属性,或者相反。属性值是可以修改的。
要密封对象,使用 Object.seal( )

1
2
3
4
5
6
7
8
9
10
11
12
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

1
2
3
4
5
6
7
var person = {
name: "阿清"
}
Object.seal(person);

console.log(Object.isSealed(person)); //true
console.log(Object.isExtensible(person)); //false

冻结对象

最严格的防篡改级别是冻结对象( frozen object)。冻结的对象既不可扩展,又是密封的,而且对象,数据属性的[ [Writable] ]特性会被设置为false。 如果定义[ [Set] ]函数,访问器属性仍然是可写的。ES5定义的Object. freeze()方法可以用来冻结对象。

1
2
3
4
5
6
7
8
9
10
var person = {
name: "阿清"
};
Object.freeze(person);
person.age = 18;
console.log(person.age); //undefined
delete person.name;
console.log(person.name); //"阿清"
person.name = "阿广";
console.log(person.name); //"阿清"

当然,也有一个Object. isFrozen()方法用于检测冻结对象。因为冻结对象既是密封的又是不可扩展的,所以用Object. isExtensible()Object.isSealed ()检测冻结对象将分别返回falsetrue

1
2
3
4
5
6
7
8
9
10
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

有一点要注意:在对防篡改对象进行非法操作时,在非严格模式是会忽略,但是在严格模式下会抛出错误。



愿你的坚持终有收获。