defineProperty的plus版-Proxy

前言

在我们面试中, 相信大家都被问到过ES6的新特性,那其中有一个就是我们不得不提的Proxy。那ES6提供的Proxy到底是是用来干嘛的呢?它和defineProperty对比的优势又是什么呢?下面我就来和大家介绍介绍这个ES6的新特性--Proxy。

Object.defineProperty

在介绍Proxy之前,我们首先需要来介绍一下Object.defineProperty。让大家了解了解直接定义或修改对象属性的方法。

Object.defineProperty 它其实是 JavaScript 中用于直接在对象上定义或修改属性的方法。它允许我们对单个属性进行精确的控制,包括设置属性的值、获取属性的值、设置属性的特性等等。使用 Object.defineProperty 我们可以定义对象的属性,并在属性访问或修改时执行自定义逻辑而不执行它本该执行的逻辑。

代码演示如下:

javascript 复制代码
let obj = {
  name: 'zhangsan',
}
let _name = 'lisi';
Object.defineProperty(obj, 'name', {
  get: function() {
    console.log('获取 name 属性');
    return _name
  },
  set: function( value) {
    console.log('设置 name 属性');
    _name = value
  }
})

console.log(obj.name);//获取
obj.name = 'wanger' // 设置
console.log(obj.name); 

如上述代码,我们使用Object.defineProperty劫持了objname 属性,同时自定义了逻辑,当我们在获取或设置name属性时,我们就执行自己自定义后的代码。我们共获取name属性时,它走get函数,当我们设置name属性时,它走set函数,打印如下:

Proxy

上面我们简单的介绍了一下Object.defineProperty方法,现在我们再来和大家细讲一下Proxy方法。

首先,Proxy是JavaScript 中的一个内置对象,它是用于创建一个可以代理目标对象的代理对象。我们可以使用 Proxy拦截并访问和修改底层对象的操作,从而实现自定义的行为。

通俗一点讲的话,可以将Proxy理解成一种拦截代理机制,它是用来在目标对象之前设置一层拦截,当我想访问这该对象时,都必须要先通过这层拦截,同时我们可以对外界的访问进行过滤和改写。

它的代码定义如下:

javascript 复制代码
const proxy = new Proxy(target, handler)
  • target: 我们要代理的目标对象
  • handler: 我们处理目标对象的处理程序对象,包含拦截对象的一组方法(部分):
    • get(target, property, receiver):拦截对目标对象属性的读取操作。
    • set(target, property, value, receiver):拦截对目标对象属性的写入操作。

代码演示如下:

javascript 复制代码
const target = {
  name: 'zhangsan',
  age: 25
};
const handler = {
  get(target, property, receiver) {
    console.log('receiver:', receiver);
    console.log(`获取 ${property} 属性`);
    return target[property];
  },
  set(target, property, value, receiver) {
    console.log(`设置 ${property} 属性为 ${value}`);
    target[property] = value;
    return true;
  }
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); 
proxy.name = 'lisi; 
console.log(proxy.name); 
console.log(target);

如上述代码, 我们将target 设置成了目标对象,同时写了一个hanler作为处理程序对象,定义了getset方法来拦截等于属性写入和读取的操作。最后,我们使用 Proxy 创建了一个代理对象 proxy,它代理了目标对象 target 并应用定义的拦截方法去拦截target的读写操作。

最后经过代码我们的目标对象target打印结果为:

Proxy强大之处

相比于Object.defineProperty, Proxy是一种更高级的代理机制,它可以对整个对象进行拦截和处理,而Object.defineProperty只能对对象的某个属性进行代理。

通过是Proxy, 我们可以直接定义handler对象来拦截并处理对目标对象的各种操作,我们还可以动态的添,移除和修改拦截的逻辑,使我们的代理更加灵活。

Object.defineProperty相比,Proxy的优点有如下几点:

  • 完善性: Proxy提供了更多广泛的拦截操作选项,拥有更多拦截和自定义的对象操作,例如:函数调用、in操作符、构造函数等。
  • 动态性: Proxy 允许我们动态地添加、移除和修改拦截逻辑,而不仅仅是在对象创建时就定义。
  • 简洁性:Proxy 的用法更简洁明了,不需要像 Object.defineProperty 那样在每个属性上进行单独的定义。

Vue3使用Proxy的原因?

我们都知道,在Vue3中数据响应式的代理机制从Object.defineProperty换成了Proxy,那在Vue3中,使用Proxy代理的主要原因有以下几点:

  1. 功能更完善:Proxy 相比于 Object.defineProperty 提供了更多的拦截方法。除了 getset,还有其他拦截方法,如 hasdeletePropertyapply 等,可以拦截更多类型的操作。
  2. 语法更简洁:Proxy 使用更直观的语法来代理目标对象,并提供了更简洁的代码结构。
  3. 自动递归监听:Proxy 可以递归地监听整个对象树结构,不需要像 Object.defineProperty 那样需要遍历对象属性进行手动递归监听。
  4. 性能优化:因为 Proxy 是 JavaScript 引擎的内置特性,它通常比 Object.defineProperty 更高效。Proxy 的性能在某些情况下可能会比 Object.defineProperty 更优秀。
  5. 错误处理方便:Object.defineProperty 在修改不能被修改的对象时会默认失败,而 Proxy 可以通过拦截方法来捕获错误并进行相应的处理。
相关推荐
UIUV几秒前
微信小程序开发学习笔记:从架构到实战
前端·javascript·前端框架
程序猿_极客2 分钟前
JavaScript的Web APIs 入门到实战(day2):事件监听与交互实现,轻松实现网页交互效果(附练习巩固)
开发语言·前端·javascript·学习笔记·web apis 入门到实战
Mintopia20 分钟前
🚀 一文看懂 “Next.js 全栈 + 微服务 + GraphQL” 的整体样貌
前端·javascript·全栈
Mintopia22 分钟前
🧬 医疗Web场景下,AIGC的辅助诊断技术边界与伦理
前端·javascript·aigc
半桶水专家27 分钟前
父子组件通信详解
开发语言·前端·javascript
Watermelo61730 分钟前
从vw/h到clamp(),前端响应式设计的痛点与进化
前端·javascript·css·算法·css3·用户界面·用户体验
Moment35 分钟前
快到  2026  年了:为什么我们还在争论  CSS 和 Tailwind?
前端·javascript·css
梵得儿SHI1 小时前
Vue 核心语法详解:模板语法中的绑定表达式与过滤器(附 Vue3 替代方案)
前端·javascript·vue.js·插值语法·vue模板语法·绑定表达式·过滤器机制
江城开朗的豌豆1 小时前
TypeScript枚举:让你的代码更有"选择权"
前端·javascript
江城开朗的豌豆1 小时前
TypeScript接口:打造你的代码“契约”之道
前端·javascript