粗解前端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能够监听数组变化
相关推荐
朴shu27 分钟前
Luckysheet 打印终极指南(预览视图+打印功能) : 2025 最新实现
前端·javascript·html
YGY Webgis糕手之路28 分钟前
Cesium 快速入门(三)Viewer:三维场景的“外壳”
前端·经验分享·笔记·vue·web
拾光拾趣录28 分钟前
模拟场景 | 前端常见问题
前端
林太白1 小时前
Rust-搞定图片上传功能
前端·后端·rust
潜心专研的小张同学1 小时前
京东云轻量云服务器与腾讯云域名结合配置网站及申请SSL证书流程详解
运维·服务器·前端
培根芝士1 小时前
Electron将视频文件单独打包成asar并调用
前端·javascript·electron
德育处主任1 小时前
p5.js 3D模型(model)入门指南
前端·前端框架·canvas
小小小小宇1 小时前
React hook的执行顺序
前端
curdcv_po2 小时前
🔥🔥🔥结合 vue 或 react,去写three.js
前端·react.js·three.js
猫头_2 小时前
uni-app 转微信小程序 · 避坑与实战全记录
前端·微信小程序·uni-app