数据劫持基础

数据劫持原理。

数据劫持,指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。

属性描述符

图片:在这里插入图片描述
图中的a并没有被删除掉

居中的图片: 在这里插入图片描述
Object.getOwnPropertyDescriptor(obj, prop)方法返回指定对象上一个自有属性对应的属性描述符,comfigurable代表可操作的,enumerable代表可遍历的,writable代表可改写的;

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

数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。有configurable、enumerable、value、writable四个配置属性。

存取描述符是由 getter 函数和 setter 函数所描述的属性。有configurable、enumerable、get、set四个配置属性。一个描述符只能是这两者其中之一;不能同时是两者。

Object.defineProperty

Object.defineProperty(obj, prop, descriptor)

obj:必需。目标对象

prop:必需。需定义或修改的属性的名字

descriptor:必需。目标属性所拥有的特性

官网响应式原理在这里插入图片描述

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

getter和setter

在这里插入图片描述在这里插入图片描述
注意:
getter: 当访问该属性时,该方法会被执行,函数的返回值会作为该属性的值返回;

setter: 当属性值修改时,该方法会被执行,该方法将接受唯一的参数,即该属性的新参数值;

不要在getter中再次获取该属性值,也不要在setter中再次设置该属性,会发生无限递归,会栈溢出

只定义getter函数:严格模式下会报错(use strict)

只定义setter函数:获取属性值为undefined;(取的是getter return的返回值)

Object.defineProperty的不足

当使用Object.defineProperty监听的对象属性是数组时,使用push、unshift、pop、shift、splice, ‘sort’, reverse是监听是触发不了set的。只要不是重新赋值一个新的数组对象,任何对数组内部的修改都不会触发set方法的执行。

不能监听属性新增和删除操作,由于js的动态性,可以为对象追加新的属性或者删除其中某个属性,这点对经过Object.defineProperty方法建立的响应式对象来说,只能追踪对象已有数据是否被修改,无法追踪新增属性和删除属性。
在这里插入图片描述
在这里插入图片描述

proxy

可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。

let proxy = new Proxy(target, handler);

target:为所要代理的目标对象(target 为一个对象)

handler :对代理对象的拦截时进行的操作

工作原理

在这里插入图片描述
在这里插入图片描述

总结

1.Proxy性能优于Object.defineProperty。 Proxy代理的是整个对象Object.defineProperty只代理对象上的某个属性,如果是多层嵌套的数据需要循环递归绑定;

2.对象上定义新属性时,Proxy可以监听到,Object.defineProperty监听不到,需要借助$set方法;

3.数组的某些方法(push、unshift和splice)Object.defineProperty监听不到,Proxy可以监听到;

猜你喜欢

转载自blog.csdn.net/weixin_36723038/article/details/128469062
今日推荐