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劫持了obj的 name 属性,同时自定义了逻辑,当我们在获取或设置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作为处理程序对象,定义了get和set方法来拦截等于属性写入和读取的操作。最后,我们使用 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 提供了更多的拦截方法。除了 get 和 set,还有其他拦截方法,如 has、deleteProperty、apply 等,可以拦截更多类型的操作。
  2. 语法更简洁:Proxy 使用更直观的语法来代理目标对象,并提供了更简洁的代码结构。
  3. 自动递归监听:Proxy 可以递归地监听整个对象树结构,不需要像 Object.defineProperty 那样需要遍历对象属性进行手动递归监听。
  4. 性能优化:因为 Proxy 是 JavaScript 引擎的内置特性,它通常比 Object.defineProperty 更高效。Proxy 的性能在某些情况下可能会比 Object.defineProperty 更优秀。
  5. 错误处理方便:Object.defineProperty 在修改不能被修改的对象时会默认失败,而 Proxy 可以通过拦截方法来捕获错误并进行相应的处理。
相关推荐
星栈4 小时前
pnpm 12 升级实测
前端·javascript
Ai-_Man5 小时前
您您这可以把Microsofat Copilot的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑·copilot
Bruce_Liuxiaowei8 小时前
网页版 DeepSeek “harness desktop“ WebGL 上下文创建失败排查实录
开发语言·javascript·webgl
小凯在掘金9 小时前
为什么箭头函数不能作为构造函数?
前端·javascript
可乐鸡翅yeah_9 小时前
网页端 M3U8 播放器性能监控,怎么看播放卡顿指标
javascript·ffmpeg·音视频·safari·m3u8
可乐鸡翅yeah_9 小时前
M3U8 防盗链 URL‑Token 签名,新手开发实操避坑
开发语言·javascript·ios·音视频·safari
2603_965896629 小时前
JS原型与原型链|对象继承与实例底层原理
开发语言·javascript·原型模式
JustHappy10 小时前
「vConsole MCP🛠️」我让 AI 直接看见任何 H5 的日志和请求帮你 debug
前端·javascript·程序员
xieter11 小时前
【技术精选】Node.js 核心事件循环机制与异步 I/O 深度剖析 (2026-10-02)
前端·javascript
想吃火锅100511 小时前
【leetcode】238.除了自身以外数组的乘积js
javascript·算法·leetcode