详解JavaScript之神奇的Object.defineProperty
摘要: JavaScript有个很神奇的Object.defineProperty(),了解一下?
=与Object.defineProperty
为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty()定义。如下:
// 示例1 |
这样看两者似乎没有区别,对吧?但是,如果使用Object.getOwnPropertyDescriptor()查看obj.a与obj.b的属性的描述描述符(property descriptor)时,会发现=与Object.defineProperty并不一样:
// 示例2 |
可知,使用=赋值时,属性的属性描述符value是可以修改的,而writable、enumerable和configurable都为true。
而使用Object.defineProperty()定义的属性的属性描述符writable、enumerable和configurable默认值为false,但是都可以修改。对于writable、enumerable和configurable的含义,从名字就不难猜中,后文也会详细介绍。
使用=赋值,等价于使用Object.defineProperty()定义时,同时将writable、enumerable和configurable设为true。代码示例3和4是等价的:
// 示例3 |
// 示例4 |
Object.defineProperty()
使用Object.defineProperty()定义时若只定义value,则writable、enumerable和configurable默认值为false。代码示例5和6是等价的:
// 示例5 |
// 示例6 |
由于writable、enumerable和configurable都是false,导致obj.name属性不能赋值、不能遍历而且不能删除:
// 示例7 |
若在严格模式(“use strict”)下,示例7中的代码会报错,下文可见。
writable
writable为false时,属性不能再次赋值,严格模式下会报错“Cannot assign to read only property”(如果你希望实时监控类似的应用错误的话,欢迎免费试用Fundebug,我们支持前端网页、微信小程序、微信小游戏,Node.js以及Java错误监控!):
// 示例8 |
writable为true时,属性可以赋值,这一点读者不妨自行测试。
enumerable
enumerable为false时,属性不能遍历:
// 示例9 |
enumerable为true时,属性可以遍历,这一点读者不妨自行测试。
configurable
enumerable为false时,属性不能删除,严格模式下会报错“Cannot delete property”:
// 示例10 |
enumerable为true时,属性可以删除,这一点读者不妨自行测试。
writable与configurable
当writable与enumerable同时为false时,属性不能重新使用Object.defineProperty()定义,严格模式下会报错“Cannot redefine property”:
// 示例11 |
当writable或者enumerable为true时,属性可以重新使用Object.defineProperty()定义,这一点读者不妨自行测试。
本文所有代码示例都在Chrome 67上测试。
参考
- Object.defineProperty()
- Object.getOwnPropertyDescriptor()
- StackOverflow: Why can’t I redefine a property in a Javascript object?
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了30亿+错误事件,付费客户有阳光保险、达令家、核桃编程、荔枝FM、微脉等众多品牌企业。欢迎大家免费试用!
版权声明: 转载时请注明作者KiwenLau以及本文地址: https://kiwenlau.com/2018/07/05/javascript-object-defineproperty/