面试官:说说Vue中Proxy与Object.defineProperty的用法与区别

前言

面试时,我们说完Vue响应式原理,或者Vue2和Vue3的区别时,通常会引出Vue3使用了Proxy来优化响应式,而面试官会继续深挖:说说Proxy与Object.defineProperty的区别。

我们不能只说Proxy直接代理一个对象,这只是一个表层表现,我们需要说出更深层的东西。

下面我们来看一下他们的用法和区别吧。

proxy

Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举等)

基本语法:

js 复制代码
/*
 * target: 目标对象
 * handler: 配置对象,用来定义拦截的行为
 * proxy: Proxy构造器的实例
 */
let proxy = new Proxy(target,handler)

基本用法

Proxy处理对象

下面是一个简单的代理obj的代码: 输出:

  1. proxy对象会根据handler里面的get set来拦截住我们的读取赋值操作。
  2. 我们修改proxy的值会映射到被代理的对象obj

💦💦那Proxy会捕获到我们更深层次的get set吗?

答案是 不会 我们这里读取a 里面的 b属性 发现只能捕获到a这个属性,说明proxy只会浅层拦截,我们需要拦截整个对象还需要手动地去实现, 我们只需要在读取的时候判断读取的值是不是一个对象,然后递归的去代理即可。

Proxy处理数组

我们可以看到Proxy是能监听到数组的修改和添加的

Object.defineProperty

bject.defineProperty() 直接在对象上定义新属性,或修改对象上的现有属性,然后返回该对象。

基础语法:

js 复制代码
/*
 * obj: 要在其上定义属性的对象
 * prop: 要定义或修改的属性的名称或Symbol
 * descriptor: 定义或修改的属性的描述符
 */
Object.defineProperty(obj, prop, descriptor)

示例

Obeject.defineProperty处理对象

js 复制代码
var obj = {}
Object.defineProperty(obj,'name',{
   value:'张三'
}

obj.name // '张三'
obj.name = '李四' // 给obj.name赋新值
console.log(obj.name) // 输出:张三 ,值还是没有改变,因为默认不可写

一次只能代理一个属性值,如果我们要代理整个对象需要在创建时递归地去给所有属性值添加上get set

Obeject.defineProperty处理数组

js 复制代码
const obj = {};

let initValue = 1;

Object.defineProperty(obj, 'name', {
  set: function(value) {
    console.log('set方法被执行了');
    initValue = value;
  },
  get: function() {
    return initValue;
  }
});

console.log(obj.name); // 1

obj.name = []; // 会执行set方法,会打印信息

// 给 obj 中的name属性 设置为 数组 [1, 2, 3], 会执行set方法,会打印信息
obj.name = [1, 2, 3];

// 然后对 obj.name 中的某一项进行改变值,不会执行set方法,不会打印信息
obj.name[0] = 11;

// 然后我们打印下 obj.name 的值
console.log(obj.name);

// 然后我们使用数组中push方法对 obj.name数组添加属性 不会执行set方法,不会打印信息
obj.name.push(4);

obj.name.length = 5; // 也不会执行set方法

我们对数组某一项值进行修改的时候是无法监听到set属性的,我们在Vue中不能简单的使用obj.name[0] = newValue,但是vue重写了修改数组的方法

'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'

总结

  1. Proxy 是一个对象的代理,Object.defineProperty只能代理某个属性
  2. Proxy可以在读取时递归代理,Object.defineProperty只能在创建时递归所有
  3. 对象上新增属性,Proxy可以监听到,Object.defineProperty不能
  4. 数组修改,Proxy可以监听到, object.defineProperty不能
  5. Proxy兼容性差
相关推荐
小满zs24 分钟前
Zustand 第五章(订阅)
前端·react.js
涵信1 小时前
第一节 基础核心概念-TypeScript与JavaScript的核心区别
前端·javascript·typescript
谢尔登1 小时前
【React】常用的状态管理库比对
前端·spring·react.js
编程乐学(Arfan开发工程师)1 小时前
56、原生组件注入-原生注解与Spring方式注入
java·前端·后端·spring·tensorflow·bug·lua
小公主2 小时前
JavaScript 柯里化完全指南:闭包 + 手写 curry,一步步拆解原理
前端·javascript
姑苏洛言4 小时前
如何解决答题小程序大小超过2M的问题
前端
GISer_Jing4 小时前
JWT授权token前端存储策略
前端·javascript·面试
开开心心就好5 小时前
电脑扩展屏幕工具
java·开发语言·前端·电脑·php·excel·batch
拉不动的猪5 小时前
es6常见数组、对象中的整合与拆解
前端·javascript·面试
GISer_Jing5 小时前
Vue Router知识框架以及面试高频问题详解
前端·vue.js·面试