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 可以通过拦截方法来捕获错误并进行相应的处理。
相关推荐
烂蜻蜓3 小时前
前端已死?什么是前端
开发语言·前端·javascript·vue.js·uni-app
Rowrey4 小时前
react+typescript,初始化与项目配置
javascript·react.js·typescript
祈澈菇凉8 小时前
Webpack的基本功能有哪些
前端·javascript·vue.js
记得早睡~9 小时前
leetcode150-逆波兰表达式求值
javascript·算法·leetcode
庸俗今天不摸鱼9 小时前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
[廾匸]10 小时前
cesium视频投影
javascript·无人机·cesium·cesium.js·视频投影
菲力蒲LY11 小时前
vue 手写分页
前端·javascript·vue.js
一丢丢@zml11 小时前
new 一个构造函数的过程以及手写 new
javascript·手写new
化作繁星12 小时前
React 高阶组件的优缺点
前端·javascript·react.js
zpjing~.~12 小时前
vue 父组件和子组件中v-model和props的使用和区别
前端·javascript·vue.js