资讯专栏INFORMATION COLUMN

数据劫持与数据代理

468122151 / 2938人阅读

摘要:数据劫持数据劫持即使用实现了的双向绑定。不输出内容数据代理即代理的意思。的拦截处理器除了外还支持多种拦截方式,具体请查阅官方文档嵌套查询。实际上也是不支持嵌套查询的。

数据劫持

数据劫持即使用Object.defineProperty()实现了vue的双向绑定。先来看看它是如何实现的

let obj = {}, txt = ""
Object.defineProperty(obj,"txt",{
    set(val) {
    
        console.log("set ....")
        txt = val || "";
    },
    get() {
        //获取obj.txt时会触发get的回调。
        console.log("get ....")
        return txt
    }
})

Object.defineProperty的缺点
1、无法监听到数组的变化
举个例子

//当被监听的属性是数组时
let arr = [1,2,3]
let obj = {}
Object.defineProperty(obj,"arr",{
    set(val) {
        console.log("set",val)
        arr = val
    },
    get() {
        console.log("get")
        return arr
    }
})
obj.arr.push(4) // get 实际上是改变arr的值但是却没有执行set而是执行了get
obj.arr = [1,2,3,4] // 执行了set

当被监听的属性是数组,这几个方法push、pop、shift、unshift、splice、sort、reverse不会触发set。vue将这几个修改原始的数组的方法称为变异方法

2、必须遍历对象的每一个属性

Object.keys(obj).forEach(key=>{
    Object.defineProperty(obj,key,{
        //....
    })
})

3、必须深层遍历嵌套对象

let person = {
    name:{
        firstName:"chan",
        lastName:"louis"
    }
}
当遇到变异方法时旧版本的vue通过重写方法来进行数据劫持
const aryMethods = ["push", "pop", "shift", "unshift", "splice", "sort", "reverse"];
const arrayAugmentations = [];
aryMethods.forEach((method)=> {
  // 这里是原生 Array 的原型方法
  let original = Array.prototype[method];
  // 将 push, pop 等封装好的方法定义在对象 arrayAugmentations 的属性上
  // 注意:是实例属性而非原型属性
  arrayAugmentations[method] = function () {
    console.log("has change");
    // 调用对应的原生方法并返回结果
    return original.apply(this, arguments);
  };
});
let list = ["a", "b", "c"];
// 将我们要监听的数组的原型指针指向上面定义的空数组对象
// 这样就能在调用 push, pop 这些方法时走进我们刚定义的方法,多了一句 console.log
list.__proto__ = arrayAugmentations;
list.push("d");  // 我被改变啦!
// 这个 list2 是个普通的数组,所以调用 push 不会走到我们的方法里面。
let list2 = ["a", "b", "c"];
list2.push("d");  // 不输出内容
Proxy数据代理

proxy即代理的意思。个人理解,建立一个proxy代理对象(Proxy的实例),接受你要监听的对象和监听它的handle两个参数。当你要监听的对象发生任何改变,都会被proxy代理拦截来满足需求。

var arr = [1,2,3]
var handle = {
    //target目标对象 key属性名 receiver实际接受的对象
    get(target,key,receiver) {
        console.log(`get ${key}`)
        // Reflect相当于映射到目标对象上
        return Reflect.get(target,key,receiver)
    },
    set(target,key,value,receiver) {
        console.log(`set ${key}`)
        return Reflect.set(target,key,value,receiver)
    }
}
//arr要拦截的对象,handle定义拦截行为
var proxy = new Proxy(arr,handle)
proxy.push(4) //可以翻到控制台测试一下会打印出什么

1、使用proxy可以解决defineProperty不能监听数组的问题,避免重写数组方法;
2、不需要再遍历key。
3、Proxy handle的拦截处理器除了get、set外还支持多种拦截方式,具体请查阅官方文档(https://developer.mozilla.org...)
4、嵌套查询。实际上proxy get()也是不支持嵌套查询的。解决方法:

let handler = {
  get (target, key, receiver) {
    // 递归创建并返回
    if (typeof target[key] === "object" && target[key] !== null) {
      return new Proxy(target[key], handler)
    }
    return Reflect.get(target, key, receiver)
  }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105370.html

相关文章

  • ES6-Proxy数据劫持(12)

    摘要:我们先以框架出发,探索其中数据劫持的奥秘。针对对象在数据劫持这个问题上,可以被认为是的升级版。技术支持监测数组的等方法操作,支持对象属性的动态添加和删除,极大的简化了响应化的代码量。 随着前端界的空前繁荣,各种框架横空出世,包括各类mvvm框架百家争鸣,比如Anglar、Vue、React等等,它们最大的优点就是可以实现数据绑定,再也不需要手动进行DOM操作了,它们实现的原理也基本上是...

    li21 评论0 收藏0
  • 中间件增强框架之InterceptFramework

    摘要:拦截之前的准备在应用启动的特定生命周期内改写字节码,植入特定的逻辑处理代码进行拦截。劫持通过字节码改写动态代理等技术,在客户端调用代码中嵌入特定处理逻辑,获取调用相关的信息,如调用地址调用协议调用结果等。 这次我们为大家带来中间件增强框架专题(MOF)的最后一篇文章,为大家讲解MOF中的InterceptFramework框架。该框架可以在应用启动过程中获取画像信息,实现应用画像数据采...

    chnmagnus 评论0 收藏0
  • Vue3.0数据双向绑定Proxy探究

    摘要:只能劫持对象的属性因此我们需要对每个对象的每个属性进行遍历。属性对于怎么拼接到和上面说到了怎么使用做数据劫持,怎么结合订阅发布,请结合数据双向绑定探究对照着数据劫持的部分去替换看一下。 前言 2018年11月16日,关注vue的人都知道这个时间点发生了什么事儿吧。vue3.0更新内容 研究数据双向绑定的大佬们都在开始猜测这个新机制了,用原生Proxy替换Object.definePro...

    stormzhang 评论0 收藏0
  • 了解MVVM及Vue实现原理,手把手带你撸源码。

    摘要:方法实现将所有属性挂载在观察对象,将每一项做一个数据劫持就是将中每一项用定义新属性并返回这个对象。当和发生变化时,自动会触发视图更新,获取得到的也就是最新值。 MVVM及Vue实现原理 Github源码地址:https://github.com/wyj2443573... mvvm 双向数据绑定数据影响视图,视图影响数据angular 脏值检测 vue数据劫持+发布订阅模式vue 不...

    cooxer 评论0 收藏0

发表评论

0条评论

468122151

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<