• JS Proxy 与 Object.defineProperty 的区别


    Object.defineProperty

    vue2.x 以及之前的版本使用 Object.defineProperty 实现数据的双向绑定,简单实现下

        let obj = {
          name: '李四',
          address: '上海浦东新区',
          flags: {
            book: {
              page: 153,
              name: 'JS'
            },
            hobby: ['足球', '游戏', '音乐']
          }
        }
        function observer(obj) {
          if (typeof obj == 'object') {
            for (let key in obj) {
              defineReactive(obj, key, obj[key])
            }
          }
        }
    
        function defineReactive(obj, key, value) {
          Object.defineProperty(obj, key, {
            get() {
              console.log('获取:' + key)
              return value
            },
            set(val) {
              observer(val)
              console.log(key + "-数据改变了")
              value = val
            }
          })
        }
    
        observer(obj)
    

      

    问题1.删除或者增加对象属性无法监听到

    问题2.数组的变化无法监听到

    问题3. 由于是使用递归遍历对象,使用 Object.defineProperty 劫持对象的属性,如果遍历的对象层级比较深,花的时间比较久,甚至有性能的问题

    proxy 

     对象用于定义基本操作的自定义行为

    简单来说就是,可以在对目标对象设置一层拦截。无论对目标对象进行什么操作,都要经过这层拦截

    let obj = {
          name: '李四',
          address: '上海浦东新区',
          flags: {
            book: {
              page: 153,
              name: 'JS'
            },
            hobby: ['足球', '游戏', '音乐']
          }
        }
    
    
        function observerProxy(obj) {
          const handler = {
            get(target, key, receiver) {
              console.log('获取:' + key) // 如果是对象,就递归添加 proxy 拦截
              if (typeof target[key] === 'object' && target[key] !== null) {
                return new Proxy(target[key], handler)
              }
              return Reflect.get(target, key, receiver)
            },
            set(target, key, value, receiver) {
              console.log('设置:' + key) // 如果是对象,就递归添加 proxy 拦截
              return Reflect.set(target, key, value, receiver)
            }
          }
          return new Proxy(obj, handler)
        }
    
        let newObj = observerProxy(obj)

    1.Object.defineProperty 拦截的是对象的属性,会改变原对象。proxy 是拦截整个对象,通过 new 生成一个新对象,不会改变原对象。

    2.proxy 的拦截方式,除了上面的 get 和 set ,还有 11 种。选择的方式很多 Proxy,也可以监听一些 Object.defineProperty 监听不到的操作,比如监听数组,监听对象属性的新增,删除等。

  • 相关阅读:
    前端之JQuery
    前端之BOM和DOM
    前端之js
    Django之创建项目、目录层级、基本操作
    前端小练习-Michael的博客界面(粗糙版)
    前端之CSS(下)
    Django简介(MVC、MTV)
    react中自定义函数、生命周期钩子函数、修改状态、组件、组件传值
    react中类组件、函数组件、state、单层遍历、多层遍历、先遍历后渲染、if-else、三目运算符
    搭建react的架手架
  • 原文地址:https://www.cnblogs.com/weblff/p/14144414.html
Copyright © 2020-2023  润新知