JavaScript中,我们希望别人无法修改我们创建的对象。比如,代码库的作者很可能想锁定核心库的某些部分来保证它们不被意外地修改。ES5中引入了三种锁定修改的级别:防止扩展preventExtensions密封seal冻结frezze

这三种级别逐渐增强。对于超过级别的行为,在非严格模式下将会悄无声息地失败,在严格模式下将会抛出一个错误。因此,建议使用严格模式,更加方便调试。

正常对象:

可以添加属性和方法,所有属性和方法可以被删除、修改。

var person = {
name: "Nicholas"
};

防止扩展:

禁止为对象添加属性和方法。但已存在的属性和方法可以被修改或删除。

实施操作:Object.preventExtensions()

检测是否应用该操作:Object.isExtensible()

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

密封:

禁止为对象删除已存在的属性和方法。被密封的对象也是不可扩展的。

实施操作:Object.seal()

检测是否应用该操作:Object.isSealed()

Object.seal(person);
console.log(Object.isExtensible(person)); // false
console.log(Object.isSealed(person)); // true
person.age = 25; // 防止扩展
console.log(person.age); // undefined
delete person.name; // 防止删除
console.log(person.name); // Nicholas

冻结:

禁止为对象修改已存在的属性和方法。所有字段均只读。被冻结的对象也是不可扩展和密封的。

实施操作:Object.freeze()

检测是否应用该操作:Object.isFrozen()

Object.freeze(person);
console.log(Object.isExtensible(person)); // false
console.log(Object.isSealed(person)); // true
console.log(Object.isFrozen(person)); // true
person.age = 25; // 防止扩展
console.log(person.age); // undefined
delete person.name; // 防止删除
console.log(person.name); // Nicholas
person.name = "Greg" // 防止修改
console.log(person.name); // Nicholas

注意:

  • 对于同一个对象,防止扩展-->密封-->冻结这种操作是不可逆的。一旦该对象被冻结,是无法恢复到防止扩展或密封状态的。一旦该对象被密封,是无法恢复到防止扩展状态的。一旦对象被锁定,它将无法解锁。
Object.freeze(person);
person.name = "Greg"; // 防止修改
console.log(person.name); // Nicholas Object.preventExtensions(person); // 无法回退
person.name = "Greg"; // 防止修改
console.log(person.name); // Nicholas
  • Object.seal()方法,会在一个现有对象上调用Object.preventExtensions(),并把所有属性标记为configurable: false
  • Object.freeze()方法,会在一个现有对象上调用Object.seal(),并把所有属性标记为writable: false
  • 深度冻结一个对象是指,首先在这个对象上调用Object.freeze(),然后遍历它引用的所有对象,并且在这些对象上调用Object.freeze()

总结:

添加 删除 修改 实施操作 检测是否应用
防止扩展 x v v Object.preventExtensions() Object.isExtensible()
密封 x x v Object.seal() Object.isSealed()
冻结 x x x Object.freeze() Object.isFrozen()

参考自《编写可维护的JavaScript》、《你不知道的JavaScript(上卷)》

JavaScript阻止修改对象的三种方式的更多相关文章

  1. 反射应用和获取Class对象的三种方式

    一.写一个"框架",可以创建任何对象运行任何方法 1.配置文件 2.使用类加载器ClassLoader,Properties集合是可以和IO流结合使用完成读取和写入数据的集合,方法 ...

  2. Java反射机制(创建Class对象的三种方式)

    1:了解什么是反射机制? 在通常情况下,如果有一个类,可以通过类创建对象:但是反射就是要求通过一个对象找到一个类的名称:   2:在反射操作中,握住一个核心概念: 一切操作都将使用Object完成,类 ...

  3. JDBC 创建连接对象的三种方式 、 properties文件的建立、编辑和信息获取

    创建连接对象的三种方式 //第一种方式 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ ...

  4. [转]javascript指定事件处理程序包括三种方式:

    javascript指定事件处理程序包括三种方式: (1):DOM0级事件处理程序 如: 代码如下: var btn=document.getElementById("mybtn" ...

  5. Java反射机制(创建Class对象的三种方式)

    1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Fi ...

  6. 反射:获取Class对象的三种方式

    获取Class对象的三种方式 package lianxiApril18; /** * 获取Class对象的三种方式 * 1 Object ——> getClass(); * 2 任何数据类型( ...

  7. Java反射获取类对象的三种方式

    package demo01; /* * 获取一个类的class文件对象的三种方式 * 1.对象获取 * 2.类名获取 * 3.Class类的静态方法获取 */ public class Reflec ...

  8. Java反射获取class对象的三种方式,反射创建对象的两种方式

    Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...

  9. 3、获取Class对象的三种方式

    3.获取Class对象的三种方式 要想对字节码文件进行解刨,必须要有字节码文件对象 Object类中的getClass方法 通过对象静态属性 .class来获取对应的Class对象 只要通过给定类的字 ...

随机推荐

  1. 并查集——poj2524(入门)

    传送门:Ubiquitous Religions 许多次WA,贴上错的代码随时警示 简单没多加修饰的并查集 [WA1] #include <iostream> #include <c ...

  2. 16常用API

    常用API 今日内容介绍 u 正则表达式 u Date u DateFormat u Calendar 第1章 正则表达式 1.1 正则表达式的概念 正则表达式(英语:Regular Expressi ...

  3. BZOJ4481 JSOI2015非诚勿扰(概率期望+树状数组)

    首先求出每个女性接受某个男性的概率.这个概率显然是一个无穷等比数列求和. 然后按编号从小到大考虑每个女性,维护出每个男性被选择的期望次数,BIT上查询后缀和即可. 需要long double. #in ...

  4. BZOJ4448 SCOI2015情报传递(离线+树链剖分+树状数组)

    即滋磁单点修改,询问路径上小于某数的值有多少个.暴力树剖套个主席树(或者直接树上主席树,似乎就1个log了?感觉不一定比两个log快)即可,然而不太优美. 开始觉得可以cdq,然而就变成log^3了. ...

  5. P1118 [USACO06FEB]数字三角形`Backward Digit Su`…

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 to N(1 \le N \ ...

  6. hdu6121 build a tree(树)

    题解: 可以考虑每一层结点的子树大小 必定满足下面的情况,即 a,a,a,a,a,a,b,c,c,c,c........ 然后每一层依次往上更新,结果是不变的 一共有logn层,所以依次扫上去,统计结 ...

  7. [洛谷P4329][COCI2006-2007#1] Bond

    题目大意:有$n$个人有$n$个任务,每个人执行每个任务有不同的成功率,每个人只能执行一个任务,求所有任务都执行的总的成功率. 题解:可以跑最大费用最大流,把成功率取个$log$,最后$exp$回去就 ...

  8. poj 3422 洛谷P2045 K取方格数(方格取数加强版)

    Description: 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来 ...

  9. BZOJ3236: [Ahoi2013]作业 树状数组维护 莫队

    水果~~~~ 关于四个while可行性的证明:区间有正确性所以不管那团小东西用没有duang~反它最终总会由于两次覆盖二准确 关于区间种数可行性的证明:他会在0 1间(或两边)来回跳动(过程中),最终 ...

  10. vector 搜索

    http://classfoo.com/ccby/article/cIBahI #include <iostream> #include <algorithm> #includ ...