每日一题之Vue数据劫持原理是什么? 您所在的位置:网站首页 vue数据劫持 每日一题之Vue数据劫持原理是什么?

每日一题之Vue数据劫持原理是什么?

2023-09-21 11:58| 来源: 网络整理| 查看: 265

什么是数据劫持?

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

简单地说,就是当我们 触发函数的时候 动一些手脚做点我们自己想做的事情,也就是所谓的 "劫持"操作

数据劫持的两种方案: Object.defineProperty Proxy 1).Object.defineProperty 语法:

Object.defineProperty(obj,prop,descriptor)

参数:

obj:目标对象 prop:需要定义的属性或方法的名称 descriptor:目标属性所拥有的特性

可供定义的特性列表:

value:属性的值 writable:如果为false,属性的值就不能被重写。 get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。 set:一旦目标属性被赋值,就会调回此方法。 configurable:如果为false,则任何尝试删除目标属性或修改属性性以下特性(writable, configurable, enumerable)的行为将被无效化。 enumerable:是否能在for…in循环中遍历出来或在Object.keys中列举出来。 例子

在Vue中其实就是通过Object.defineProperty来劫持对象属性的setter和getter操作,并“种下”一个监听器,当数据发生变化的时候发出通知,如下:

var data = { name:'test'} Object.keys(data).forEach(function(key){ Object.defineProperty(data,key,{ enumerable:true, configurable:true, get:function(){ console.log('get'); }, set:function(){ console.log('监听到数据发生了变化'); } }) }); data.name //控制台会打印出 “get” data.name = 'hxx' //控制台会打印出 "监听到数据发生了变化"

上面的这个例子可以看出,我们完全可以控制对象属性的设置和读取。在Vue中,在很多地方都非常巧妙的运用了Object.defineProperty这个方法,具体用在哪里并且它又解决了哪些问题,下面就简单的说一下:

监听对象属性的变化

它通过observe每个对象的属性,添加到订阅器dep中,当数据发生变化的时候发出一个notice。 相关源代码如下:(作者采用的是ES6+flow写的,代码在src/core/observer/index.js模块里面)

export function defineReactive ( obj: Object, key: string, val: any, customSetter?: Function ) { const dep = new Dep()//创建订阅对象 const property = Object.getOwnPropertyDe述 //属性的描述特性里面如果configurable为false则属性的任何修改将无效 if (property && property.configurable === false) { return }scriptor(obj, key)//获取obj对象的key属性的描 // cater for pre-defined getter/setters const getter = property && property.get const setter = property && property.set let childOb = observe(val)//创建一个观察者对象 Object.defineProperty(obj, key, { enumerable: true,//可枚举 configurable: true,//可修改 get: function reactiveGetter () { const value = getter ? getter.call(obj) : val//先调用默认的get方法取值 //这里就劫持了get方法,也是作者一个巧妙设计,在创建watcher实例的时候,通过调用对象的get方法往订阅器dep上添加这个创建的watcher实例 if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() } if (Array.isArray(value))


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有