要记住Object.defineProperty
可不只有get和set两个属性哦~
属性:
-
configurable:当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
默认为false。 -
enumerable:当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中(决定属性是否可遍历)。
默认为false。 - 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。
默认为undefined。 -
writable:当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。
默认为false。 - get和set。
configurable有点变态,主要说一下:
var b = Object.creat(null);
Object.defineProperty(b, "a", {
configurable: true,
writable: false,
value: "fuck"
});
- 当configurable为true时,表示该属性【可被设置】和【可被删除】。
被设置的意思是还可以使用defineProperty重新设置。
被删除的意思可以使用delete b.a 此属性。 - 当configurable为false时,有意思地方来了~首先【不可被删除】是肯定的,我们主要讨论一下能否【被设置】。
此时如果writable为true,那么你仅可以设置writable和value。writable可以由true改为 false,但是不能由false改为true。
此时如果writable为false,那么所有行为都不可以再改变了,再调用Object.defineProperty会报错。
总结:
configurable为false时,writable可以由true改为 false,但是不能由false改为true。其他行为都不可以修改。
应用:
先介绍下object.preventExtensions(...)
:个人觉得这个方法没什么可单独使用的场景。使用该方法之后对象的确是不能拓展了,但是已有属性TMD可被删。
-
密封:
Object.seal()
会创建一个密封的对象,这个方法实际上会在一个现有对象上调用object.preventExtensions(...)
并把所有现有属性标记为configurable:false。
所以, 密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性(虽然可以改属性的值) -
冻结:
Object.freeze()
会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal()
,并把所有现有属性标记为writable: false,这样就无法修改它们的值。你可以深度冻结一个对象,具体方法为,首先这个对象上调用Object.freeze()
然后遍历它引用的所有对象,并在这些对象上调用Object.freeze()
。
补充:
我们平时使用var a = {}
定义的对象,configurable、enumerable、writable默认值都为true,而value为你自己设定的值,如果不设定的话则为undefined。
参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。