放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 前端

    • 前端 概览
    • 前端汇总

    • front 博文

    • front 项目总结

    • front 高级

    • front tools

  • vue

    • vue 概览
    • vue 汇总

    • vue 博文

    • vue 项目总结

    • vue 高级

  • html

    • html 概览
    • html 汇总

    • html 博文

  • css

    • css 概览
    • css 汇总

    • css 博文

    • sass

    • less

  • js

    • javascript 概览
    • JS 汇总

    • ES6

      • let 和 const 命令
      • promise
      • async
      • class
      • set
      • map
      • 迭代器iterator
      • Proxy
        • Proxy
        • Object.defineProperty
          • Proxy 和 Object.defineProperty 的对比
    • JS 博文

    • JS 工具

  • node

    • node 概览
    • node 汇总

    • node 框架

    • node 博文

  • react

    • react 概览
    • react 汇总

    • react 博文

    • react 高级

  • 微信小程序

    • 微信小程序 概览
    • 微信小程序总结
    • 微信小程序文章
    • 微信小程序 博文

    • 微信小程序 高级

  • 微信公众号

    • 微信公众号 概览
    • 微信公众号总结
    • 微信公众号文章
  • 多端开发

    • 多端开发
    • dsbridge 概览
    • jsbridge 概览
    • webview
    • uniapp

      • uniapp 概览
    • taro

      • taro 概览
    • flutter

      • flutter 概览
      • flutter 环境搭建
    • electron

      • electron 概览
  • front
放肆青春
2021-09-29

Proxy

# Proxy

Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。

其实就是在对目标对象的操作之前提供了拦截,可以对外界的操作进行过滤和改写,修改某些操作的默认行为,这样我们可以不直接操作对象本身,而是通过操作对象的代理对象来间接来操作对象,达到预期的目的~

Proxy 的优势如下

  1. Proxy 可以直接监听整个对象而非属性。
  2. Proxy 可以直接监听数组的变化。
  3. Proxy 有 13 中拦截方法,如 ownKeys、deleteProperty、has 等是 Object.defineProperty 不具备的。
  4. Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  5. Proxy 做为新标准将受到浏览器产商重点持续的性能优化,也就是传说中的新标准的性能红利。

Proxy 的缺点如下:

  1. proxy 有兼容性问题,无完全的 polyfill

proxy 为 ES6 新出的 API,浏览器对其的支持情况可在 w3c 规范中查到,通过查找我们可以知道,

虽然大部分浏览器支持 proxy 特性,但是一些浏览器或者低版本不支持 proxy,

因此 proxy 有兼容性问题,那能否像 ES6 其他特性有 polyfill 解决方案呢?,

这时我们通过查询 babel 文档,发现在使用 babel 对代码进行降级处理的时候,并没有合适的 polyfill

  1. 第二个问题就是性能问题

proxy 的性能其实比 promise 还差,

这就需要在性能和简单实用上进行权衡,例如 vue3 使用 proxy 后,

其对对象及数组的拦截很容易实现数据的响应式,尤其是数组

# Object.defineProperty

Object.defineProperty 的优势如下

兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平。

Object.defineProperty 不足在于:

  1. Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。
  2. Object.defineProperty 不能监听数组。是通过重写数据的那 7 个可以改变数据的方法来对数组进行监听的。
  3. Object.defineProperty 也不能对 es6 新产生的 Map,Set 这些数据结构做出监听。
  4. Object.defineProperty 也不能监听新增和删除操作,通过 Vue.set()和 Vue.delete 来实现响应式的。

问题:Object.defineProperty 真的无法监测数组下标的变化吗?

注意:Object.defineProperty 本身是可以监控到数组下标的变化的,只是在 Vue 的实现中,从性能/体验的性价比考虑

Object.defineProperty 在数组中的表现和在对象中的表现是一致的,数组的索引就可以看做是对象中的 key

  1. 通过索引访问或设置对应元素的值时,可以触发 getter 和 setter 方法。

  2. 通过 push 或 unshift 会增加索引,对于新增加的属性,需要再手动初始化才能被 observe。

  3. 通过 pop 或 shift 删除元素,会删除并更新索引,也会触发 setter 和 getter 方法。

所以,Object.defineProperty 是有监控数组下标变化的能力的,只是 Vue2.x 放弃了这个特性。

# Proxy 和 Object.defineProperty 的对比

  1. Proxy 是直接代理对象;而 Object.defineProperty 只能劫持对象的属性,

  2. Proxy 能监听对象的新增和删除操作;Object.defineProperty 不能监听对象的新增和删除操作,通过 Vue.set()和 Vue.delete 来实现响应式的。

  3. Proxy 可以直接监听数组的变化;Object.defineProperty 本身是有监控数组下标变化的能力的,只是在 Vue 的实现中,从性能/体验的性价比考虑

  4. Proxy 支持 13 种拦截操作,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的。

  5. Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的;而 Object.defineProperty 只能遍历对象属性直接修改;

  6. Proxy 兼容性差;Object.defineProperty 兼容性好,支持 IE9,

  7. Proxy 有性能问题但是有新标准性能红利,从长远来看,JS 引擎会继续优化 Proxy


参考:为什么 Vue3.0 不再使用 defineProperty 实现数据监听? (opens new window)

更新时间: 1/11/2022, 7:30:26 PM
迭代器iterator
js 基础语法

← 迭代器iterator js 基础语法→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式