ES5阻止修改对象的方法

Posted by Jiazhi on 2016-10-31

阻止修改

在js开发中,我们需要创建和维护很多的对象。在多人协作的开发中,同一个对象可能会由不同的人来维护。如果你是这个对象的作者,很可能想锁定该对象来保证它不会被意外的修改,来避免程序意外出错的可能。

ECMAScript5引入了几个方法来防止对对象的修改。使用这些方法,可以锁定这些对象,保证任何人不能有意或无意地修改这些对象。

有以下三种锁定修改的级别:

  • 防止扩展
    禁止为该对象“添加”属性和方法,但已存在的属性和方法是可以被修改或删除。

  • 密封
    在“防止修改”的基础上,还禁止“删除”该对象已存在的属性和方法。

  • 冻结
    在“密封”的基础上,还禁止“修改”该对象已存在的属性和方法。

每个锁定的类型都对应两个方法:一个用来锁定,另一个用来检测是否已被锁定。

防止修改

Object.preventExtensions()用来对对象实施防止扩展操作,Object.isExtensible()用来检测对象是否已被防止扩展。

var person = {
name: 'Jiazhi';
}

// 防止扩展
Object.preventExtensions(person);
console.log(Object.isExtensible(person)); // false

person.age = 23; // 禁止扩展
console.log(person.age); // undefined

在上面的例子中,锁定了person对象防止被扩展,所有调用Object.isExtensible()函数返回false

在非严格模式下,试图为person对象新增属性或者方法将会悄悄地失败。在严格模式下,则会抛出一个错误。

密封

Object.seal()函数用来密封一个对象,Object.isSealed()函数用来检测对象是否已被密封。

var person = {
name: 'Jiazhi';
}

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

delete person.name; // 禁止删除
console.log(person.name); // Jiazhi

在上面的例子中,person对象被密封,所有调用Object.isSealed()函数返回true,而且被密封的对象同时也是不可扩展的,所以调用Object.isExtensible()函数返回false

同样的,也是只有在严格模式下,试图删除属性或者方法才会抛出一个错误。

冻结

Object.freeze()函数用来冻结一个对象,Object.isFrozen()函数用来检测对象是否已被冻结。

var person = {
name: 'Jiazhi';
}

// 冻结
Object.freeze(person);
console.log(Object.isExtensible(person)); // false
console.log(Object.isSealed(person)); // true
console.log(Object.isFrozen(person)); // true

person.name = 'Xiaoming'; // 禁止修改
console.log(person.name); // Jiazhi

在上面的例子中,person对象被冻结,禁止任何对已存在属性或方法的修改,所以调用Object.isFrozen()函数返回true。被冻结的对象同时也是不可扩展和密封的,所以调用Object.isExtensible()函数返回false,调用Object.isSealed()函数返回true

在非严格模式下,这种操作将会悄悄失败,只有在严格模式下,尝试去修改才会抛出一个错误。

最后

使用这些ES5的方法可以保证你的对象不会被意外的修改。不过要注意的是,我们需要在全部定义好这些对象的功能之后,才能使用这些锁定的方法,因为一旦对象被锁定了,就无法解锁。