一、数据属性描述符

对象是一个属性集合,对象的基本特征是属性名(name)和属性值(value)。ES5 增加了属性描述符,可以更细腻的控制属性的不同操作。属性描述符有 configurable、writable 和 enumerable。

属性描述符通常和 Object.defineProperty/Object.defineProperties 一起使用来定义属性,它也会受到诸如 Object.freeze/Object.seal 等方法改变。

1. configurable 当且仅当 configurable 为 true 时,该属性才能够被改变,也能够被删除(delete),默认为 false

  1. var obj = {}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. value: 'John'
  5. })
  6. // 不能 delete
  7. delete obj.name // false
  8.  
  9. Object.defineProperty(obj, 'name', {
  10. configurable: true,
  11. value: 'John'
  12. })
  13. // 可以delete
  14. delete obj.name // true

2. writable 当且仅当 writable 为 true 时,该属性才能被赋值运算符(=)改变,默认为 false

  1. var obj = {}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. value: 'John'
  5. })
  6. obj.name = 'Backus' // 修改不起作用,仍然是 John,严格模式中会报错阻止修改
  7.  
  8. Object.defineProperty(obj, 'name', {
  9. writable: true,
  10. value: 'John'
  11. })
  12. obj.name = 'Backus' // 被改为了 backus

3. enumerable 当且仅当 enumerable 为 true 时,该属性才能够出现在对象的枚举属性(for in)中,默认为 false

  1. var obj = {}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. value: 'John'
  5. })
  6. // 不能遍历
  7. for (var a in obj) {
  8. console.log(a) // 无输出
  9. }
  10.  
  11. Object.defineProperty(obj, 'name', {
  12. enumerable: true,
  13. value: 'John'
  14. })
  15. // 可以遍历
  16. for (var a in obj) {
  17. console.log(a) // 输出 "name"
  18. }

ES6 的 Object.keys 只返回 enumerable=true 的属性

  1. var obj = {name: 'John'}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. value: 'Backus',
  5. enumerable: true
  6. })
  7. Object.defineProperty(obj, 'age', {
  8. value: 30,
  9. enumerable: false
  10. })
  11.  
  12. Object.keys(obj) // ['name']

可以通过 propertyIsEnumerable 方法判断属性的 enumerable 值

  1. obj.propertyIsEnumerable('name') // true
  2. obj.propertyIsEnumerable('age') // false

4. 使用 ES3(传统的) JSON 方式定义对象,其 configurable/writable/enumerable 默认都是 true,如下

  1. var obj = {name: 'John', age: 30}
  2.  
  3. // configurable
  4. delete obj.name // true
  5. // writable
  6. obj.age = 32 // true
  7. // enumerable
  8. for (var a in obj) {
  9. console.log(a) // age
  10. }

也即

  1. var obj = {name: 'John', age: 30}

等同于

  1. Object.defineProperty(obj, 'name', {
  2. value: 'John',
  3. configurable: true,
  4. writable: true,
  5. enumerable: true
  6. })
  7. Object.defineProperty(obj, 'age', {
  8. value: 33,
  9. configurable: true,
  10. writable: true,
  11. enumerable: true
  12. })

  

5. 使用 ES5 的 Object.defineProperty/Object.defineProperties 方式定义对象,其 configurable/writable/enumerable 默认都是 false,如下

  1. var obj = {}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. value: 'John'
  5. })
  6. Object.defineProperty(obj, 'age', {
  7. value: 33
  8. })
  9.  
  10. // configurable
  11. delete obj.name // false
  12. // writable
  13. obj.age = 32 // false
  14. // enumerable
  15. for (var a in obj) {
  16. console.log(a) // 无输出,不能遍历
  17. }

也即

  1. Object.defineProperty(obj, 'name', {
  2. value: 'John'
  3. })

等同于

  1. Object.defineProperty(obj, 'name', {
  2. value: 'John',
  3. configurable: false,
  4. writable: false,
  5. enumerable: false
  6. })

数据属性描述符汇总如下

二、存取属性描述符

存取描述符是由一对 getter-setter 函数功能来描述的属性,格式为

  1. name: {
  2. get: function() { ... },
  3. set: function(newVal) { ... },
  4. enumerable: true,
  5. configurable: true
  6. }

例如

  1. var obj = {}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. configurable: true,
  5. enumerable: true,
  6. get: function() {
  7. console.log('get')
  8. return this.value
  9. },
  10. set: function(newVal) {
  11. console.log('set')
  12. this.value = newVal
  13. }
  14. })
  15.  
  16. // 赋值会调用 set 方法
  17. obj.name = 'John'
  18. // 取值会调用 get 方法
  19. obj.name

与上述的属性描述符只能存在一种,即二选一,不能同时存在,否则会报错

  1. var obj = {}
  2.  
  3. // 错误方式一
  4. Object.defineProperty(obj, 'name', {
  5. value: 'John',
  6. get: function() {
  7. console.log('get')
  8. return this.value
  9. }
  10. })
  11.  
  12. // 错误方式二
  13. Object.defineProperty(obj, 'name', {
  14. writable: true,
  15. get: function() {
  16. console.log('get')
  17. return this.value
  18. }
  19. })

Firefox 报错如下

存取描述符汇总如下

三、和属性描述符相关的几个函数

  1. Object.defineProperty
  2. Object.defineProperties
  3. Object.getOwnPropertyDescriptor

Object.defineProperty 上面已经介绍过,Object.defineProperties 批量定制对象属性,内部其实循环方式调用 Object.defineProperty

  1. Object.defineProperties(obj, {
  2. name: {
  3. value: 'John',
  4. writable: true
  5. },
  6. age: {
  7. value: 30,
  8. enmuerable: true
  9. }
  10. })

Object.getOwnPropertyDescriptor 返回该对象某属性的描述器,描述器自身是一个对象

  1. var obj = {}
  2.  
  3. Object.defineProperty(obj, 'name', {
  4. value: 'Backus',
  5. writable: true,
  6. enumerable: true
  7. })
  8.  
  9. var des = Object.getOwnPropertyDescriptor(obj, 'name')
  10. console.log(des)

输出如图

ES5 数据属性描述符和存取描述符的更多相关文章

  1. usb协议分析-设备描述符配置包-描述符

    /* usb协议分析仅供大家参考---设备描述符配置包,设备描述符, 地址设置, 配置描述符, 字符串描述符 */ /* -1- usb设备描述符配置包 */ typedef struct _USB_ ...

  2. (转)USB的描述符及各种描述符之间的依赖关系

    全文链接:http://justmei.blog.163.com/blog/static/11609985320102421659260/?latestBlog 1 推荐 [原创] USB入门系列之七 ...

  3. STM32 USB设备描述符、配置描述符、端点描述符含义

    查了一整天的资料,自己把不懂的全部试了一遍 一下是程序以及注释 /* USB设备描述符*/ const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ ...

  4. 学习C#修饰符:类修饰符和成员修饰符

    C#修饰符之类修饰符:public.internal. partial.abstract.sealed.static C#修饰符之成员修饰符:public.protected.private.inte ...

  5. 2016 2 - 23 arc中的所有权修饰符(_strong修饰符与_weak修饰符)

    一 _strong修饰符 1._strong修饰符是id类型和对象类型默认的所有权修饰符.如下: id obj = [[NSObject alloc] init];//在没用明确变量所有权修饰符时,会 ...

  6. 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例

    [源码下载] 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例 作者:webabcd 介绍背水一战 Windows 10 之 资源 资源限定符概述 资源限定符示例 ...

  7. 说说ID选择符、类选择符和HTML标记选择符的优先级顺序

    ID选择符.类选择符和HTML标记选择符三者之间的优先级顺序是:ID选择符>类选择符>HTML标记选择符,但是可以用!important提升优先权. 如:       p{color:#f ...

  8. 换行符 '\n' 和 回车符 '\r' 的区别?

    顾名思义: 换行符就是另起一新行,光标在新行的开头: 回车符就是光标回到一旧行的开头:(即光标目前所在的行为旧行) ------------------------------------------ ...

  9. 解决 openpyxl 垂直分页符和水平分页符同时添加的问题

    前言 十天前知乎上有人提问 python:openpyxl模块怎么给表格添加分页符?实现分页打印功能?,看到问题之后,我很快的给他了一个如何添加垂直分页符或水平分页符的示例,你以为问题就结束了?我是这 ...

随机推荐

  1. Ionic2学习笔记(5):Provider

    作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5547646.html             Provider是一种为App提供数据源的方式, 举个 ...

  2. BizTalk Server 2016

    10月28日微软正式发布BizTalk第十个版本BizTalk Server 2016,陆续发布了Azure VM镜像.MSDN版本.开发者版本等.以下为BizTalk Server 2016 新特性 ...

  3. WCF 数据数据 DataTable

    一般在WCf数据大数据是 List集合 或者 Json. public DataTable GetProperitybyModelCode(string modelCode) { using (var ...

  4. div+css页面右侧底部悬浮层

    效果体验:http://hovertree.com/texiao/css/23/ 效果图: 代码如下: <!DOCTYPE html> <html> <head> ...

  5. EF Core1.0 CodeFirst为Modell设置默认值!

    当我们使用CodeFirst时,有时候需要设置默认值! 如下 ; public string AdminName {get; set;} = "admin"; public boo ...

  6. SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据问题

    原因分析 首先我们来看下Spring mvc 中文件上传的配置 <bean id="multipartResolver" class="org.springfram ...

  7. Spring2.0-applicationContext.xml中使用el表达式给实体类属性赋值被当成字符串-遁地龙卷风

    (-1)写在前面 这两天读<javaweb开发王者归来>,学到Spring的PropertyPlaceholderConfigurer时出现一个问题,我已${jdbc.name}的形式赋值 ...

  8. java web学习总结(六) -------------------servlet开发(二)

    一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...

  9. react引用ant的table组件

    import React from 'react';import '../../css/uicss/UI.css';import 'antd/lib/style/index.less';import ...

  10. 可轮播滚动的Tab选项卡

    前段时间有试着搭建个后台主题ui框架,有用到可支持滚动的Tab选项卡,模仿着H+后台主题ui框架中的代码造轮子改造了下,可惜代码在公司,不能把代码外发出来(感觉这样被限制了很多,对于这样的公司没办法, ...