ES5 数据属性描述符和存取描述符
一、数据属性描述符
对象是一个属性集合,对象的基本特征是属性名(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 报错如下
存取描述符汇总如下
三、和属性描述符相关的几个函数
- Object.defineProperty
- Object.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)
输出如图
ES5 数据属性描述符和存取描述符的更多相关文章
- usb协议分析-设备描述符配置包-描述符
/* usb协议分析仅供大家参考---设备描述符配置包,设备描述符, 地址设置, 配置描述符, 字符串描述符 */ /* -1- usb设备描述符配置包 */ typedef struct _USB_ ...
- (转)USB的描述符及各种描述符之间的依赖关系
全文链接:http://justmei.blog.163.com/blog/static/11609985320102421659260/?latestBlog 1 推荐 [原创] USB入门系列之七 ...
- STM32 USB设备描述符、配置描述符、端点描述符含义
查了一整天的资料,自己把不懂的全部试了一遍 一下是程序以及注释 /* USB设备描述符*/ const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ ...
- 学习C#修饰符:类修饰符和成员修饰符
C#修饰符之类修饰符:public.internal. partial.abstract.sealed.static C#修饰符之成员修饰符:public.protected.private.inte ...
- 2016 2 - 23 arc中的所有权修饰符(_strong修饰符与_weak修饰符)
一 _strong修饰符 1._strong修饰符是id类型和对象类型默认的所有权修饰符.如下: id obj = [[NSObject alloc] init];//在没用明确变量所有权修饰符时,会 ...
- 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例
[源码下载] 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例 作者:webabcd 介绍背水一战 Windows 10 之 资源 资源限定符概述 资源限定符示例 ...
- 说说ID选择符、类选择符和HTML标记选择符的优先级顺序
ID选择符.类选择符和HTML标记选择符三者之间的优先级顺序是:ID选择符>类选择符>HTML标记选择符,但是可以用!important提升优先权. 如: p{color:#f ...
- 换行符 '\n' 和 回车符 '\r' 的区别?
顾名思义: 换行符就是另起一新行,光标在新行的开头: 回车符就是光标回到一旧行的开头:(即光标目前所在的行为旧行) ------------------------------------------ ...
- 解决 openpyxl 垂直分页符和水平分页符同时添加的问题
前言 十天前知乎上有人提问 python:openpyxl模块怎么给表格添加分页符?实现分页打印功能?,看到问题之后,我很快的给他了一个如何添加垂直分页符或水平分页符的示例,你以为问题就结束了?我是这 ...
随机推荐
- Ionic2学习笔记(5):Provider
作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5547646.html Provider是一种为App提供数据源的方式, 举个 ...
- BizTalk Server 2016
10月28日微软正式发布BizTalk第十个版本BizTalk Server 2016,陆续发布了Azure VM镜像.MSDN版本.开发者版本等.以下为BizTalk Server 2016 新特性 ...
- WCF 数据数据 DataTable
一般在WCf数据大数据是 List集合 或者 Json. public DataTable GetProperitybyModelCode(string modelCode) { using (var ...
- div+css页面右侧底部悬浮层
效果体验:http://hovertree.com/texiao/css/23/ 效果图: 代码如下: <!DOCTYPE html> <html> <head> ...
- EF Core1.0 CodeFirst为Modell设置默认值!
当我们使用CodeFirst时,有时候需要设置默认值! 如下 ; public string AdminName {get; set;} = "admin"; public boo ...
- SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据问题
原因分析 首先我们来看下Spring mvc 中文件上传的配置 <bean id="multipartResolver" class="org.springfram ...
- Spring2.0-applicationContext.xml中使用el表达式给实体类属性赋值被当成字符串-遁地龙卷风
(-1)写在前面 这两天读<javaweb开发王者归来>,学到Spring的PropertyPlaceholderConfigurer时出现一个问题,我已${jdbc.name}的形式赋值 ...
- java web学习总结(六) -------------------servlet开发(二)
一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...
- react引用ant的table组件
import React from 'react';import '../../css/uicss/UI.css';import 'antd/lib/style/index.less';import ...
- 可轮播滚动的Tab选项卡
前段时间有试着搭建个后台主题ui框架,有用到可支持滚动的Tab选项卡,模仿着H+后台主题ui框架中的代码造轮子改造了下,可惜代码在公司,不能把代码外发出来(感觉这样被限制了很多,对于这样的公司没办法, ...