当前位置: 首页 > news >正文

JavaScript中监听对象的操作方式

文章目录

  • 前言
  • 一、对象
    • 1. 声明语法
    • 2. 声明语法
    • 3. 二者唯一区别
  • 二、Object.defineProperty
  • 三、属性描述符
    • 1. 数据描述符
    • 2. 存取描述符
    • 3. 错误操作导致报错
  • 总结


前言

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中监听对象的描述符的讲解

相关文章:

  • 网站开发的背景与环境/网站如何提升seo排名
  • wordpress 关闭警告/网站排名优化+o+m
  • 如何设置一个网站/百度手机助手官方正版
  • 织梦本地做网站/seo西安
  • 名校建设专题网站/郑州疫情最新消息
  • wordpress 隐藏内容插件/微信营销
  • 初探WebSocket
  • 1. 先看一个实际需求,引出 Git
  • 第1章:Hello HTML转PDF
  • Redis在IDEA中的使用方法之配置redisConfig类
  • 【愚公系列】2022年10月 .Net Core使用cpolar内网穿透功能实现钉钉回调事件的监听
  • 基于海马优化算法的函数寻优算法
  • 一周技术学习笔记(第85期)-两篇文章13个问题重入OO设计思想
  • 智能合约学习笔记——僵尸工厂(一)
  • Vue中实现放大镜效果
  • 【电商数仓】数仓即席查询之Presto简介,安装,Presto优化之数据存储、查询SQL、一些注意事项
  • 【C++笔试强训】第五天
  • linux调试器——gdb