详解js对象中属性的两种类型之数据属性和访问器属性
作者:矢心
前言
在理解vue底层响应式原理时,了解到,原来对象中的属性,不单单从表面看起来那么简单是key:value
形式,而是还有隐藏的内部特性
其中对象内的属性 分为两种类型的属性:数据属性 和 访问器属性
ECMAScript 规范中定义:对象是一种无序属性的集合,每个属性都是一个键值对,其中键是字符串或 Symbol 类型,值可以是数据值或访问器函数
其中对象是 有序 还是 无序 的问题,可以移步我的其他的文章参考
这里主要讲到 数据属性 和 访问器属性 是什么,有什么作用
数据属性
数据属性是日常默认使用的类型,就是我们常见的方式
使用 对象字面量 或者 new Object 方式创建
// 对象字面量 const obj = { name: '小涛' // 这个name就是数据属性 } // new Object const obj2 = new Object({ name: '小涛' // 这个name就是数据属性 })
而这个数据属性有以下4个描述其行为的特性。分别是:
[[Configurable]]:是否可配置,该属性是否可以被删除或修改特性,当修改这个特性为false时,不能通过delete删除属性,同时也不能再次修改其他的特性,包括不能改为访问器属性
注意:一旦将属性的 configurable 特性定义为 false ,即不可配置的,该属性就不能再改回可配置的了。此后,再调用 Object.defineProperty() 方法修改除了 writable 特性的特性都会导致错误。(JavaScript 高级程序设计)
[[Enumerable]]:是否可枚举,如果为不可枚举,则不能通过 for-in 循环或者 Object.keys() 返回该属性
[[Writable]]:是否可修改,是否可以修改属性的值
[[Value]]:这个属性的属性值,写入属性值的时候,把值保存在这个位置;读取属性值的时候,从这个位置读。默认值为 undefined
当我们通过 对象字面量 或者 new Object 方式创建的对象时,它们属性的特性默认都为true
当我们通过 Object.defineProperty() 来定义新的属性时,对于没有明确定义的特性,默认为false
下面我通过 Object.defineProperty() 分别演示一下这些特性
[[Configurable]] 是否可配置
const obj = {} Object.defineProperty(obj, 'name', { configurable: false, // 不可配置 value: '小涛' }) delete obj.name // 删除无效 console.log(obj, obj.name) // {name: '小涛'} '小涛' // 除了writable,无法重新配置 Object.defineProperty(obj, 'name', { // 报错: Cannot redefine property: name atFunction.defineProperty enumerable: true })
[[Enumerable]] 是否可枚举
const obj = {} Object.defineProperty(obj, 'name', { enumerable: false, // 不可枚举 value: '小涛' }) console.log(obj.name, Object.keys(obj)) // 小涛 []
访问器属性
访问器属性是对象属性中,另外一种类型,在对象中使用 get/set 创建
它也有一下4个描述其行为的特性。分别是:
[[Configurable]]:是否可配置,该属性是否可以被删除或修改特性,当修改这个特性为false时,不能通过delete删除属性,同时也不能再次修改其他的特性,包括不能改为访问器属性
[[Enumerable]]:是否可枚举,如果为不可枚举,则不能通过 for-in 循环或者 Object.keys() 返回该属性
[[Get]]:用于读取属性值的函数。如果该属性没有 getter 函数,则该特性值为 undefined
[[Set]]:用于设置属性值的函数。如果该属性没有 setter 函数,则该特性值为 undefined
在vue2中,正是利用 访问器属性,通过 Object.defineProperty 把对象中的属性 全部转化为访问器属性中的 getter/setter,来实现响应式
可以直接在 对象中使用get/set 或者通过 Object.defineProperty定义get/set 两种方式来使用
对象中使用
const obj = { _value: '', get value() { return this._value }, set value(newVal) { this._value = newVal } } console.log(obj.value)
obj.value即为响应式属性
Object.defineProperty 中使用
const obj = {} Object.defineProperty(obj, 'value', { get() { return '小涛测试' }, set(newValue) { console.log('获取更新', newValue) } }) obj.value = '1111'
怎么获取属性描述符/特性
如果想要判断对象内属性的特性可以使用**Object.getOwnPropertyDescriptor()或Object.getOwnPropertyDescriptors()**获取单个属性或全部属性的 属性描述符/特性
const obj = {} Object.defineProperty(obj, 'name', { enumerable: false, // 不可枚举 writable: true, // 可修改 value: '小涛' }) console.log(Object.getOwnPropertyDescriptor(obj, 'name'))
以上就是详解js对象中属性的两种类型之数据属性喝访问器属性的详细内容,更多关于js 数据属性喝访问器属性的资料请关注脚本之家其它相关文章!