粗解前端Proxy和defineProperty以及他们的区别

一.Object.defineProperty

1.基本概念

Object.defineProperty()是ES5提供的一个方法,用于直接在对象上定义新属性或者修改现有属性,并且返回该对象。

2.核心功能

js 复制代码
Object.defineProperty(obj, prop, descriptor)
  • obj: 要在其上定义属性的对象
  • prop:要定义或修改属性的名称
  • descriptor:将被定义或修改的属性描述符

3.属性描述符类型

(1)数据描述符

js 复制代码
{
    value: any,           // 属性值
    writable: boolean,    // 是否可写
    enumberable: boolean, // 是否可枚举
    configurable: boolean // 是否可配置
}

(2)存取描述符

js 复制代码
{
    get: function() {},  // 获取属性值
    set: function() {},  // 设置属性值
    enumberable: boolean,//
    configurable: booleab//
}

4.Vue2中的实现

Vue2使用Object.defineProperty()实现数据响应式

js 复制代码
function defineReactive(obj, key, val) {
    Object.defineProperty(obj, key, {
        enumberable: true,
        configurable: true,
        get() {
            console.log(`获取${key}: ${value}`)
            return val;
        },
        set(newVal) {
            if (newVal === val) return;
            console.log(`设置${key}: ${newVal}`);
            val = newVal
        }
    });
}

5.局限性

  • 无法检测对象属性的添加或删除
  • 数组变异方法需要特殊处理
  • 需要递归遍历对象所有属性

二.Proxy

1.基本概念

Proxy 是ES6引入的新特性,用于创建对象的代理,从而实现对基本操作的拦截和自定义。

2.基本语法

js 复制代码
const proxy = new Proxy(target, handler);
  • target: 要包装的目标对象
  • handler: 拦截操作对象

3.常用拦截操作

js 复制代码
const handler = {
    get(target, prop, receiver) {},        // 拦截属性读取
    set(target, prop, value, receiver) {}, // 拦截属性设置
    deleteProperty(target, prop) {},       // 拦截属性删除
    has(target, prop) {},                  // 拦截in操作符
    // ...一共13中拦截操作
}

4.Vue3中的实现

Vue3使用Proxy重构响应式系统:

js 复制代码
function reactive(obj) {
    return new Proxy(obj, {
        get(target, key, receiver) {
            console.log(`获取${key}`);
            return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
            console.log(`设置${key}: ${value}`);
            return Reflect.set(target, key, value, receiver);
        }
    });
}

5.优势

  • 直接监听整个对象而非属性
  • 支持数组变化检测
  • 13种拦截操作更全面
  • 性能更好

三.Proxy和defineProperty的对比

  • Proxy拦截操作更全面
  • Proxy初始化性能较慢,但后续运行时性能和内存占用都较低,defineProperty相反
  • Proxy不兼容IE浏览器
  • Proxy能够监听数组变化
相关推荐
一只小阿乐2 分钟前
react 点击事件注意事项
前端·javascript·react.js·react
Mike_jia8 分钟前
EMQX:开源MQTT消息中间件王者,百万级物联网连接的首选引擎
前端
xiaoxue..12 分钟前
深入理解JavaScript中的深拷贝与浅拷贝:内存管理的艺术
开发语言·前端·javascript·面试
Mapmost14 分钟前
【高斯泼溅】深度解析Three.js 加载3D Gaussian Splatting模型
前端
鹏多多36 分钟前
详解React组件状态管理useState
前端·javascript·react.js
excel44 分钟前
如何将 MP4 文件转换为 M3U8 格式并实现流媒体播放
前端
秋氘渔1 小时前
Vue基础语法及项目相关指令详解
前端·javascript·vue.js
IT_陈寒1 小时前
React性能优化实战:我用这5个技巧将组件渲染速度提升了70%
前端·人工智能·后端
邱泽贤1 小时前
uniapp 当前页调用上一页的方法
前端·javascript·uni-app
不一样的少年_1 小时前
大部分人都错了!这才是chrome插件多脚本通信的正确姿势
前端·javascript·浏览器