JavaScript 性能优化之防篡改对象

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

不可扩展对象

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

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

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

        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() 方法可以确定该对象是否为可扩展对象。

        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( )

        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

冻结对象

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

        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

        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

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



愿你的坚持终有收获。

你可能感兴趣的:(javascript学习路程)