JavaScript对象不变性知多少

栏目: JavaScript · 发布时间: 6年前

内容简介:ES5开始所有的属性都有了属性描述符,以表示属性的一些特性。 我们可以通过Object.getOwnPropertyDescriptor(...)查看属性描述符。这里我们只讨论其中的writable(可写)、configurable(可配置),我们可以通过Object.defineProperety(...)来配置属性描述符。 当设置了writable为false时,该属性的值无法修改。当设置了configurable为false时,无法重新配置该属性的特性,且无法删除该属性,该操作是不可逆的。(唯一可以设

ES5开始所有的属性都有了属性描述符,以表示属性的一些特性。 我们可以通过Object.getOwnPropertyDescriptor(...)查看属性描述符。

let obj = {a: 'a'};
let descriptor = Object.getOwnPropertyDesciptor(obj, 'a');
//descriptor: {value: 'a', writable: true, enumerable: true, configurable: true}
复制代码

这里我们只讨论其中的writable(可写)、configurable(可配置),我们可以通过Object.defineProperety(...)来配置属性描述符。 当设置了writable为false时,该属性的值无法修改。

Object.defineProperty(obj, 'a', {writable: false});
obj.a = 'b'; //obj.a = 'a'
复制代码

当设置了configurable为false时,无法重新配置该属性的特性,且无法删除该属性,该操作是不可逆的。(唯一可以设置的情况是,将writable为true 改为writable为false)

Object.defineProperty(obj, 'a', {configurable: false});
delete obj.a //obj.a = 'a';
Object.defineProperty(obj, 'a', {configurable: true}); //Type Error
Object.defineProperty(obj, 'a', {writable: false});
obj.a = 'aa'; //obj = {a: 'a'}
复制代码

禁止扩展

Object.preventExtensions(...)防止后续向对象新增属性。

let obj = {a: 'a'};
Object.preventExtensions(obj);
obj.b = 'b'; //obj = {a: 'a'}
console.log(Object.isExtensible(obj)); //false
复制代码

密封对象

Object.seal(...)可以创建一个密封的对象,该对象的属性不可扩展、配置、删除,但可以修改。实际上该方法就是对对象先用Object.preventExtensions禁止扩展属性,再将对象所有属性的configurable特性设置false。

let obj = {a: 'a', b: 'b'};
Object.seal(obj);
obj.c = 'c'; //obj = {a: 'a', b: 'b'}
delete obj.a;
delete obj.b; //obj = {a: 'a', b: 'b'}
obj.a = 'aa'; //obj = {a: 'aa', b: 'b'}
console.log(Object.isSealed(obj)); //true
复制代码

冻结对象

Object.freeze(...)可以创建一个冻结的对象,该对象的属性不可扩展、配置、删除、修改,是js中对象最高不可变性。实际上该方法就是调用Object.seal(...)将对象设置成密封对象后,在将所有数据访问属性设置为writable:false。

let obj = {a: 'a', b: 'b'};
Object.freeze(obj);
obj.c = 'c'; //obj = {a: 'a', b: 'b'}
delete obj.a;
delete obj.b; //obj = {a: 'a', b: 'b'}
obj.a = 'aa'; //obj = {a: 'a', b: 'b'}
console.log(Object.isFrozen(obj)); //true
复制代码

这个方法是你可以应用在对象上的级别最高的不可变性,它会禁止对于对象本身及其任意直接属性的修改(不过这个对象引用的其他对象是不受影响的)。 ###注意 这里对象中的不可变性都是浅不变性,如果属性引用的是对象、数组等引用类型,该引用的对象、数组本身都是可变的(比如往数组里添加元素),除非再把每个引用类型属性递归冻结。

let obj = {a: [1, 2]};
Object.freeze(obj);
obj.a.push(3); //obj = {a: [1, 2, 3]}
复制代码

本文旨在互相学习,本文属个人理解,有说的不对的地方,师请纠正。转载请注明原帖


以上所述就是小编给大家介绍的《JavaScript对象不变性知多少》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First Python

Head First Python

Paul Barry / O'Reilly Media / 2010-11-30 / USD 49.99

Are you keen to add Python to your programming skills? Learn quickly and have some fun at the same time with Head First Python. This book takes you beyond typical how-to manuals with engaging images, ......一起来看看 《Head First Python》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具