一、数据属性描述符

对象是一个属性集合,对象的基本特征是属性名(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
})

数据属性描述符汇总如下

二、存取属性描述符

存取描述符是由一对 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 报错如下

存取描述符汇总如下

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

  1. Object.defineProperty
  2. Object.defineProperties
  3. 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)

输出如图

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. Windows下程序启动时出现0xc000007b错误的解决方案

    一.背景介绍 不久前用Qt开发了一款小工具在公司使用,Debug运行时一切正常.可是当Release编译发布打包之后,运行时弹出这样的提示框: 略一思考,首先排除了DLL缺失的可能性.我知道Qt应用程 ...

  2. [译] Paxos算法详解

    1. 概述 Paxos算法被用来实现一个容错的分布式系统,一直以来以晦涩难懂著称.这可能是因为该算法最开始使用希腊文表述的.事实上,它是所有分布式算法中最简单易懂的.Paxos算法的本质其实就是一个共 ...

  3. 使用SignalR实现即时通讯功能

    教程简介 SignalR的好处是可以让多个客户端之间进行互动,比如这篇教程就展示了当你在页面上拖动矩形方块的同时,其它打开这个页面的用户也将会看到你拖动的轨迹以及最终的结果,当然他们也可以通过拖动该方 ...

  4. [WCF编程]12.事务:服务事务编程(下)

    一.投票与提交 虽然WCF负责事务传播及两阶段提交协议的管理工作,但是 她不知道事务是否应该提交或终止.这需要根服务告诉WCF应该何时启动两阶段提交协议.是提交还是终止.WCF提供了两种编程模式来对事 ...

  5. 【开源】SoDiaoEditor 可能是目前最好用的开源电子病历编辑器(B/S架构)

    此刻我的内心是忐忑的,这个标题给了我很大的压力,虽然很久以前我就在github上搜索一圈了,也没发现有其他更好的开源电子病历编辑器,如各位亲发现有更好的,烦请知会我一声. 该编辑器其实已经憋了很久了, ...

  6. 创建javaScript对象的方法

    一.工厂模式 function person (name,age) { var p=new Object(); p.name=name; p.age=age; p.showMessage=functi ...

  7. Elasticsearch 的坑爹事——记录一次mapping field修改过程

    Elasticsearch 的坑爹事 本文记录一次Elasticsearch mapping field修改过程 团队使用Elasticsearch做日志的分类检索分析服务,使用了类似如下的_mapp ...

  8. SSH输入错误Action

    在类型转化.输入验证校验 .文件上传等出错的时候,如Action中某个变量是int,而上传的值是"ABC",此时Action不会执行execute()函数,而是直接返回result ...

  9. Linux Ctrl+c与ctrl+z的区别

    提问:CTRL-Z和CTRL-C区别?回答:CTRL-Z和CTRL-C都是中断命令,但是他们的作用却不一样.CTRL-C是强制中断程序的执行,而CTRL-Z的是将任务中断,但是此任务并没有结束,他仍然 ...

  10. 大公司c#&.net转型java的原因有哪些?

    历来就听说有编程语言“鄙视链”的说法,而如今月经贴上的那些事儿,还真让我给遇到了. 以下内容来自知乎,纯属扯淡,易引发口水战,看完勿人身攻击. 目的给盲目的公司决策者.开发人员科普下,有个客观清醒的认 ...