JavaScript中监听对象的操作方式

👨 作者简介:大家好,我是Taro,前端领域创作者
✒️ 个人主页:唐璜Taro
🚀 支持我:点赞👍+📝 评论 + ⭐️收藏



前言

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。


一、对象

对象可以通过两种形式定义,声明形式和构造形式

1. 声明形式

var myObj = {
 key: value
 //...
}

2. 构造形式

var myObj = new Object()
myObj.key = value

3. 二者唯一区别

在声明形式中,可以添加多个 键 / 值对,但是在构造形式中必须逐个添加属性


构造形式:
在这里插入图片描述


二、Object.defineProperty

由上面的例子可以看出,无论是通过声明形式构造形式创建对象,该对象都可以枚举(即通过 for...in Object.keys 方法获取到该对象的属性值)且属性值可以后续更改

但是在某些特定的场景下,我们定义完对象之后,在后续操作不让更改其属性值或者无法枚举,这种应该怎么操作呢?

于是 Object.defineProperty() 来了


在这里插入图片描述


三、属性描述符

  • 目前属性描述符有两种主要形式:数据描述符和存取描述符

  • 数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的

  • 存取描述符是由 getter 函数和 setter 函数所描述的属性

  • 一个描述符只能是这两者其中之一;不能同时是两者

1. 数据描述符

有了属性描述符,可以更加细腻的控制属性的不同操作,它们分别为:

  1. configurable //属性值是否可以改变
  2. writable //是否能写入
  3. enumerable //支持枚举

属性描述符通常和 Object.defineProperty 一起定义属性

2. 存取描述符

存取描述符由一对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 = '猪八戒'

// 取值会调用 get 方法
obj.name

3. 错误操作导致报错

在这里插入图片描述

TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute

转载

这个错误是因为:Object.defineProperty(object, propertyName, descriptor) 定义新属性时,descriptor 中同时有 访问器(getter/setter) 与 value/writable 属性。

如果一个描述符同时拥有 value 或 writable 和 get 或 set 键,则会产生一个异常

测试代码

var obj = {}

// value和 get 只能同时用一个
Object.defineProperty(obj, 'name', {
	value: '孙悟空',
	get: function() {
		console.log('get')
		return this.value
	}
})

// writable和set只能同时用一个
Object.defineProperty(obj, 'name', {
	writable: true,
	set: function(newValue) {
		console.log('set')
	}
})
  • Object.defineProperty 的设计初衷,并不是为了监听劫持一个对象中所有属性的

  • 如果想要监听更多的操作,比如新增、删除属性,那么Object.definePropertys是没法办法做到的

Object.defineProperty 是Vue2中的响应式核心

优点:

  • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平

缺点:

  • 只能劫持对象的属性,对每个对象的每个属性都要进行遍历
  • 不能监听数组。是通过重写数据的那7个可以改变数据的方法来对数组进行监听的
  • 不能对 es6 新产生的 Map,Set 这些数据结构做出监听
  • 对于监听新增和删除操作,通过 Vue.set()和 Vue.delete来实现响应式的

总结

以上就是JavaScript中监听对象的描述符的讲解

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值