关于object.definedProperty
最近开始看vue.js
的原理以及源码(真的是没有无缘无故去读源码,为了面试也好,为了和框架知已知彼也好,多学点总没错的吧😂),关于数据侦听这块,vue.js
主要是用了Object.defineProperty()
不过Object.defineProperty()
也存在很多缺陷,但是对这个属性方法不熟悉的我,阅读源码时遇到了很多不便利,查了网上资料,自己整理一下Object.defineProperty()
的用法Object.defineProperty()
用于在一个对象上新增属性或者修改已有属性,举个🌰
1 | let myObj = { |
对象的属性描述符(就是对象属性的属性)一般分为两种,一种就是数据属性描述符(属性的读写属性一类),另一种就是存取描述符(给属性修改值或者获取属性值),
主要看存取描述符:
get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
默认为undefined
。
set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
默认为 undefined。
试用一下
1 | let oldValue = 18 |
对于vue
中对象属性的观察来说,其实就是利用了Object.defineProperty()
方法,get
收集依赖,set
触发依赖,我的理解,所谓收集依赖就是找到所有用到改变数据的地方,触发依赖就是修改这些数据
仿照vue.js
中的写法,把上面的🌰重写一下
1 | // Observer函数 |
然后再看下Object.defineProperty()
的缺陷: 在对象上新增和删除属性都无法被追踪到。
20191001 火曜日 更新
纸上得来终觉浅 昨天在项目中遇到了关于这个object.defineProperty()
中的这个坑。
需求内容是:根据后端传过来的数据渲染表格数据,然后当再次从输入框输入相应查询数据时,将对应行数据的状态status
状态置为正常。
按照需求,当第二次输入查询对应内容的时候,我将tableData
数组中对应的那一条对象数据status
属性改成了正常
,打印数据也是对的,但是表格UI
界面没有任何变化,我就纳闷了….
后来仔细看了接口数据,发现后段给的数据中,也就是我一开始拿到的tableData
中根本没有status
字段,相当于触及了object.defineProperty()
无法侦听对象的属性新增或者删除这个情况。bug算是找到出处了,接下来就是要解决,baidu
了一波,发现了vue
中自带解决这个问题的方法,使用Vue.set( target, propertyName/index, value )
向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = ‘hi’)
或者不用这个方法的话,就是一开始就给数据加上这个status
属性,赋值为空的字符串也行,遇到bug不可怕,遇不到bug才可怕吧。
谨此一记。😄