ES5 数据属性描述符和存取描述符
2016-03-15 07:32
387 查看
一、数据属性描述符
对象是一个属性集合,对象的基本特征是属性名(name)和属性值(value)。ES5 增加了属性描述符,可以更细腻的控制属性的不同操作。属性描述符有 configurable、writable 和 enumerable。属性描述符通常和 Object.defineProperty/Object.defineProperties 一起使用来定义属性,它也会受到诸如 Object.freeze/Object.seal 等方法改变。
1. configurable 当且仅当 configurable 为 true 时,该属性才能够被改变,也能够被删除(delete),默认为 false
var obj = {} Object.defineProperty(obj, 'name', { value: 'John' }) // 不能 delete delete obj.name // false Object.defineProperty(obj, 'name', { configurable: true, value: 'John' }) // 可以delete delete obj.name // true
2. writable 当且仅当 writable 为 true 时,该属性才能被赋值运算符(=)改变,默认为 false
var obj = {} Object.defineProperty(obj, 'name', { value: 'John' }) obj.name = 'Backus' // 修改不起作用,仍然是 John,严格模式中会报错阻止修改 Object.defineProperty(obj, 'name', { writable: true, value: 'John' }) obj.name = 'Backus' // 被改为了 backus
3. enumerable 当且仅当 enumerable 为 true 时,该属性才能够出现在对象的枚举属性(for in)中,默认为 false
var obj = {} Object.defineProperty(obj, 'name', { value: 'John' }) // 不能遍历 for (var a in obj) { console.log(a) // 无输出 } Object.defineProperty(obj, 'name', { enumerable: true, value: 'John' }) // 可以遍历 for (var a in obj) { console.log(a) // 输出 "name" }
ES6 的 Object.keys 只返回 enumerable=true 的属性
var obj = {name: 'John'} Object.defineProperty(obj, 'name', { value: 'Backus', enumerable: true }) Object.defineProperty(obj, 'age', { value: 30, enumerable: false }) Object.keys(obj) // ['name']
可以通过 propertyIsEnumerable 方法判断属性的 enumerable 值
obj.propertyIsEnumerable('name') // true obj.propertyIsEnumerable('age') // false
4. 使用 ES3(传统的) JSON 方式定义对象,其 configurable/writable/enumerable 默认都是 true,如下
var obj = {name: 'John', age: 30} // configurable delete obj.name // true // writable obj.age = 32 // true // enumerable for (var a in obj) { console.log(a) // age }
也即
var obj = {name: 'John', age: 30}
等同于
Object.defineProperty(obj, 'name', { value: 'John', configurable: true, writable: true, enumerable: true }) Object.defineProperty(obj, 'age', { value: 33, configurable: true, writable: true, enumerable: true })
5. 使用 ES5 的 Object.defineProperty/Object.defineProperties 方式定义对象,其 configurable/writable/enumerable 默认都是 false,如下
var obj = {} Object.defineProperty(obj, 'name', { value: 'John' }) Object.defineProperty(obj, 'age', { value: 33 }) // configurable delete obj.name // false // writable obj.age = 32 // false // enumerable for (var a in obj) { console.log(a) // 无输出,不能遍历 }
也即
Object.defineProperty(obj, 'name', { value: 'John' })
等同于
Object.defineProperty(obj, 'name', { value: 'John', configurable: false, writable: false, enumerable: false })
数据属性描述符汇总如下
![](http://images2015.cnblogs.com/blog/114013/201603/114013-20160314175248881-1367437520.jpg)
二、存取属性描述符
存取描述符是由一对 getter-setter 函数功能来描述的属性,格式为name: { get: function() { ... }, set: function(newVal) { ... }, enumerable: true, configurable: true }
例如
var obj = {} Object.defineProperty(obj, 'name', { configurable: true, enumerable: true, get: function() { console.log('get') return this.value }, set: function(newVal) { console.log('set') this.value = newVal } }) // 赋值会调用 set 方法 obj.name = 'John' // 取值会调用 get 方法 obj.name
与上述的属性描述符只能存在一种,即二选一,不能同时存在,否则会报错
var obj = {} // 错误方式一 Object.defineProperty(obj, 'name', { value: 'John', get: function() { console.log('get') return this.value } }) // 错误方式二 Object.defineProperty(obj, 'name', { writable: true, get: function() { console.log('get') return this.value } })
Firefox 报错如下
![](http://images2015.cnblogs.com/blog/114013/201603/114013-20160314175357990-105145308.jpg)
存取描述符汇总如下
![](http://images2015.cnblogs.com/blog/114013/201603/114013-20160314175528662-1453627744.jpg)
三、和属性描述符相关的几个函数
Object.definePropertyObject.defineProperties
Object.getOwnPropertyDescriptor
Object.defineProperty 上面已经介绍过,Object.defineProperties 批量定制对象属性,内部其实循环方式调用 Object.defineProperty
Object.defineProperties(obj, { name: { value: 'John', writable: true }, age: { value: 30, enmuerable: true } })
Object.getOwnPropertyDescriptor 返回该对象某属性的描述器,描述器自身是一个对象
var obj = {} Object.defineProperty(obj, 'name', { value: 'Backus', writable: true, enumerable: true }) var des = Object.getOwnPropertyDescriptor(obj, 'name') console.log(des)
输出如图
![](http://images2015.cnblogs.com/blog/114013/201603/114013-20160314175810974-287339420.jpg)
相关文章推荐
- js阻塞特性
- bzoj1103 大都市 树状数组
- linux build commands
- typedef详解
- Is there any way to define a min and max value for edittext in android?
- 求每个月的最后一天日期
- SSH框架实现仿淘宝购物demo
- SSH框架实现仿淘宝购物demo
- C++转iOS开发5个月总结
- [mysql] mysql explain 使用
- IOS开发者必看的博客汇总
- 冒泡排序-数字篇
- IOS开发者必看的博客
- 冒泡排序-字符篇
- 1857: [Scoi2010]传送带 三分套三分
- 面试官最爱问的设计模式-单例模式
- LVM 类型的 Storage Pool - 每天5分钟玩转 OpenStack(8)
- lintcode-medium-Binary Tree Maximum Path Sum
- python利用or在列表解析中调用多个函数.py
- 关于波峰波谷趋势分割(想象中的方法),判断趋势,突然来想到的,记下来,没有实验。以便以后用于分割