粗解前端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能够监听数组变化
相关推荐
海带紫菜菠萝汤几秒前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm
名字还没想好☜8 分钟前
React 受控输入框光标跳到末尾:格式化输入时的 selection 丢失 bug 与修复
前端·javascript·react.js·bug·react·next.js
Access开发易登软件8 分钟前
Access 怎么做前后端分离?用 Web API 读写 SQL Server
前端·数据库·人工智能·microsoft·excel·access
10share17 分钟前
React 新一代样式隔离方案 —— 编译时、零运行时、原生写法
前端·react.js
Revolution6128 分钟前
Node.js 是什么:前端项目里哪些事情由它完成
前端·面试·node.js
我要两颗404西柚1 小时前
Stage three:VUE工程化与实战工具
前端·javascript·vue.js
光影少年1 小时前
RN 的EventEmitter 双向通信
前端·react native·react.js
布鲁飞丝1 小时前
从零实现富文本编辑器#-浏览器选区与编辑器选区模型同步
java·前端·编辑器
写不来代码的草莓熊2 小时前
Cesium 地图交互绘制圆形、多边形
前端·javascript·地图
weixin_427771612 小时前
前端版本检测
前端