为JavaScript对象新增或者修改属性,有两种不一样方式:直接使用=赋值或者使用Object.defineProperty 定义,使用后者的话还能够设置属性的描述符。函数
Object.defineProperty(obj, prop, descriptor) 接受三个参数:this
属性描述符是一个对象,做用就是定义一个属性的属性 (-,-)。他有两种主要形式:数据描述符和存取描述符。code
数据描述符是一个具备值的属性,该值多是可写的,也可能不是可写的,特有属性:value、writable。存取描述符是由getter-setter函数对描述的属性,特有属性:get、set。描述符必须是这两种形式之一;不能同时是二者。对象
Object.getOwnPropertyDescriptor() 能够获取指定对象上一个自有属性对应的属性描述符。
继承
数据描述符和存取描述符均具备如下可选键值:ip
表示对象的该属性是否能够被删除,以及其余特性是否能够被修改(除了能够单向改变 writable 为 false)。默认为 false。get
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) // {}
当定义了对象的属性是否能够在 for...in 循环和 Object.keys() 中被枚举。默认为 false。it
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"]
数据描述符具备如下可选键值:io
该属性对应的值。能够是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。console
当且仅当该属性的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}
存取描述符同时具备如下可选键值:
一个给属性提供 getter 的方法,若是没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,可是会传入this对象(因为继承关系,这里的this并不必定是定义该属性的对象)。
一个给属性提供 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