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 可以通过拦截方法来捕获错误并进行相应的处理。
相关推荐
一颗花生米。15 分钟前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
学习使我快乐0119 分钟前
JS进阶 3——深入面向对象、原型
开发语言·前端·javascript
bobostudio199520 分钟前
TypeScript 设计模式之【策略模式】
前端·javascript·设计模式·typescript·策略模式
勿语&1 小时前
Element-UI Plus 暗黑主题切换及自定义主题色
开发语言·javascript·ui
一路向前的月光6 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   6 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web6 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
Jiaberrr7 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
安冬的码畜日常9 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
太阳花ˉ9 小时前
html+css+js实现step进度条效果
javascript·css·html