为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty 定义,使用后者的话还可以设置属性的描述符。

Object.defineProperty

Object.defineProperty(obj, prop, descriptor) 接受三个参数:

  1. obj:要在其上定义属性的对象。
  2. prop:要定义或修改的属性的名称。
  3. descriptor:将被定义或修改的属性描述符。

属性描述符

属性描述符是一个对象,作用就是定义一个属性的属性 (-,-)。他有两种主要形式:数据描述符和存取描述符。

数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的,特有属性:value、writable。存取描述符是由getter-setter函数对描述的属性,特有属性:get、set。描述符必须是这两种形式之一;不能同时是两者。

Object.getOwnPropertyDescriptor() 可以获取指定对象上一个自有属性对应的属性描述符。




数据描述符和存取描述符均具有以下可选键值:

1. configurable

表示对象的该属性是否可以被删除,以及其他特性是否可以被修改(除了可以单向改变 writable 为 false)。默认为 false。

let Tom = {}
Object.defineProperty(Tom, 'height', {
value: 174
})
delete Tom.height
console.log(Tom) // {height: 174}
let Tom = {}
Object.defineProperty(Tom, 'height', {
value: 174,
configurable: true
})
delete Tom.height
console.log(Tom) // {}

2. enumerable

当定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。默认为 false。

let Tom = {}
Object.defineProperty(Tom, 'height', {
value: 174
})
Object.keys(Tom) // []
let Tom = {}
Object.defineProperty(Tom, 'height', {
value: 174,
enumerable: true
})
Object.keys(Tom) // ["height"]






数据描述符具有以下可选键值:

1. value

该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

2. writable

当且仅当该属性的writable为true时,value才能被赋值运算符 “=” 改变。默认为 false。

let Tom = {}
Object.defineProperty(Tom, 'height', {
value: 174
})
Tom.height = 180
console.log(Tom) // {height: 174} Object.getOwnPropertyDescriptor(Tom,'height')
// {value: 174, writable: false, enumerable: false, configurable: false}
let Tom = {}
Object.defineProperty(Tom, 'height', {
value: 174,
writable: true
})
Tom.height = 180
console.log(Tom) // {height: 180}

使用“=”定义属性时,writable/enumerable/configurable 都为true:

let Tom = {}
Tom.height = 174 Object.getOwnPropertyDescriptor(Tom,'height')
// {value: 180, writable: true, enumerable: true, configurable: true}

存取描述符同时具有以下可选键值:

1. get

一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。

2. set

一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

let Tom = {
realHeight: 173
} Object.defineProperty(Tom, 'height', {
get: function() {
console.log('报高一点')
return this.realHeight + 5;
},
set: function(value) {
console.log('现在高' + value + 'cm')
this.realHeight = value
}
}) Object.getOwnPropertyDescriptor(Tom,'height')
// {get: ƒ, set: ƒ, enumerable: false, configurable: false} Tom.height // 178
Tom.height = 169
Tom.height // 174

Object.defineProperty 与 属性描述符的更多相关文章

  1. JS属性描述符之Object.defineProperty()定义对象属性特性

    一.Object.defineProperty的作用 用来给对象新增属性,和修改对象中的属性. 二.JS对象中的描述符 js对象中两种属性描述符:数据描述符和存取描述符(访问描述符). 注意事项: 1 ...

  2. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

  3. JavaScript 属性描述符

    属性描述符(Property Descriptor)是 ES5 之后出现的概念,顾名思义,它用于描述属性应该是什么样,例如是否只读,能否枚举,能否可配置等.所有对象属性均可使用属性描述符来定义. 属性 ...

  4. JS属性描述符

    var myObject = { a:2 }; Object.getOwnpropertyDescriptor(myObject,"a"); { value:2, writable ...

  5. JS - 属性描述符各配置的默认值的注意事项

    通过字面量或者obj.x = 1;创建的属性 与 通过Object.defineProperty创建的属性,他们的属性描述符的默认值是不同的,前者都为true,后者都为false.

  6. js 面向对象之属性描述符

    上回介绍了面向对象之构造器属性.这次介绍下属性描述符 遍历对象属性 let person = {name: "lisi"} for (key in person) { consol ...

  7. JavaScript.descriptor(属性描述符)

    属性描述符是对JavaScript属性的描述,包括:value.writable.enumerable.configurable,除value其他默认为true. 本文包括: 取得属性描述符. Obj ...

  8. vue2.x版本中Object.defineProperty对象属性监听和关联

    前言 在vue2.x版本官方文档中 深入响应式原理 https://cn.vuejs.org/v2/guide/reactivity.html一文的解释当中,Object.defineProperty ...

  9. Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)

    Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...

随机推荐

  1. LeetCode 386——字典序的第 K 小数字

    1. 题目 2. 解答 字典序排数可以看做是第一层节点分别为 1-9 的十叉树,然后我们在树上找到第 K 小的数字即可.因此,我们需要分别统计以 1-9 为根节点的每个树的节点个数.如果 K 小于当前 ...

  2. POJ 3304 Segments(线的相交判断)

    Description Given n segments in the two dimensional space, write a program, which determines if ther ...

  3. JavaScript初探系列之面向对象

    面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装.继承.多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义J ...

  4. iOS-获取webView的高度

    - (void)webViewDidFinishLoad:(UIWebView *)wb{ //方法1 CGFloat documentWidth = [[wb stringByEvaluatingJ ...

  5. TCP系列20—重传—10、早期重传(ER)

    一.介绍 在前面介绍thin stream时候我们介绍过有两种场景下可能不会产生足够的dup ACK来触发快速重传,一种是游戏类响应交互式tcp传输,另外一种是传输受到拥塞控制的限制,只能发送少量TC ...

  6. 微信小程序 功能函数 计时器

    let lovetime = setInterval(function () { let str = '(' + n + ')' + '重新获取' that.setData({ getText2: s ...

  7. go的IO函数,整理下最基本的IO处理函数,工欲善其事必先利其器

    bufio.NewScanner()函数是一行一行地读,但是对/proc/函数,这里不是个好方法,最好是把所有的数据一次读完,然后再去读,有没有这样读的接口呢?把所有数据都读入到内存中然后再通过通过搜 ...

  8. mysql,oracle,sql server中的默认事务隔离级别查看,更改

    未提交读(隔离事务的最低级别,只能保证不读取物理上损坏的数据) 已提交读(数据库引擎的默认级别) 可重复读 可序列化(隔离事务的最高级别,事务之间完全隔离) 可串行化比较严谨,级别高; MySQL m ...

  9. c#调用系统默认软件打开应用

    System.Diagnostics.Process.Start(),参数为对应的应用路径 System.Diagnostics.Process.Start(((FileInfo)lv.Selecte ...

  10. K-means聚类算法与EM算法

    K-means聚类算法 K-means聚类算法也是聚类算法中最简单的一种了,但是里面包含的思想却不一般. 聚类属于无监督学习.在聚类问题中,给我们的训练样本是,每个,没有了y. K-means算法是将 ...