Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【揭秘Vue核心】深入解析Object.defineProperty和Proxy的区别,让你秒懂!

【揭秘Vue核心】深入解析Object.defineProperty和Proxy的区别,让你秒懂!

作者头像
奋飛
发布于 2023-07-10 03:41:08
发布于 2023-07-10 03:41:08
79702
代码可运行
举报
文章被收录于专栏:Super 前端Super 前端
运行总次数:2
代码可运行

问题:Object.difinePropertyproxy 有什么区别?

Object.definePropertyProxy 是用于实现响应式数据的两种不同方式。

Object.defineProperty

Object.defineProperty 通过直接修改对象的属性描述符来实现数据的劫持。Vue 2.x 中就是通过 Object.defineProperty 来实现数据的响应式。但是 Object.defineProperty 有一些限制,比如只能劫持已经存在的属性,无法对新增属性或删除属性进行劫持。这就导致 Vue 2.x 需要在创建实例之前声明数据属性,否则无法实现响应式。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Object.defineProperty(obj, prop, descriptor)

属性

类型

描述

value

任意类型

设置属性的值。

writable

布尔值

指定属性是否可写。默认为 false,即属性是只读的。

enumerable

布尔值

指定属性是否可枚举。默认为 false,即属性不会出现在 for…in 循环和 Object.keys() 中。

configurable

布尔值

指定属性是否可配置。默认为 false,即不可删除并且禁止修改属性的特性(writable、enumerable 和 configurable)。

get

函数类型

获取属性值的函数。

set

函数类型

设置属性值的函数。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let obj = {}
Object.defineProperty(obj, "b", {
  get() {
    return bValue;
  },
  set(newValue) {
    bValue = newValue;
  },
  enumerable: true,
  configurable: true,
});
proxy

而 Vue 3.0 使用了 Proxy,它是 ES6 新增的特性。**Proxy 可以对整个对象进行劫持,包括对新增属性和删除属性的劫持。**它提供了一种编程范式的改变,可以更加灵活地监听和代理对象的操作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const p = new Proxy(target, handler)

方法

作用

get(target, prop, receiver)

拦截对目标对象属性的读取操作,并返回相应的值。

set(target, prop, value, receiver)

拦截对目标对象属性的写入操作,并进行相应的处理。

has(target, prop)

拦截对 in 操作符的操作,判断属性是否存在于目标对象中。

deleteProperty(target, prop)

拦截对 delete 操作符的操作,删除目标对象的指定属性。

apply(target, thisArg, arguments)

拦截函数的调用操作,并进行相应的处理。

construct(target, arguments, newTarget)

拦截对目标对象使用 new 操作符创建实例的操作,并进行相应的处理。

getPrototypeOf(target)

拦截对目标对象的原型的读取操作,并返回相应的值。

setPrototypeOf(target, proto)

拦截对目标对象的原型的写入操作,并进行相应的处理。

isExtensible(target)

拦截对目标对象是否可扩展的判断操作。

preventExtensions(target)

拦截对目标对象添加新属性的操作,并进行相应的处理。

getOwnPropertyDescriptor(target, prop)

拦截对目标对象属性描述符的读取操作,并返回相应的属性描述符。

defineProperty(target, prop, descriptor)

拦截对目标对象属性描述符的写入操作,并进行相应的处理。

ownKeys(target)

拦截对 Object.getOwnPropertyNames 和 Object.getOwnPropertySymbols 的操作,返回目标对象所有自身属性的键名。

enumerate(target)

拦截对 for…in 循环的操作,返回目标对象所有可枚举的属性名。

通过在 handler 中实现这些方法,我们可以自定义拦截操作的行为,并对底层的对象进行劫持和改变。这使得我们能够更灵活地操作和控制对象的访问、修改和行为。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onst handler = {
    get: function(obj, prop) {
        return prop in obj ? obj[prop] : 37;
    }
};

const p = new Proxy({}, handler);
对比

Proxy 相比于 Object.defineProperty 的优势:

  • Proxy 可以代理整个对象,而不是单个属性,可以实现更细粒度的拦截和操作。
  • Proxy 可以监听新增属性和删除属性的操作,不需要事先声明属性。

Object.defineProperty 相比于 Proxy 的·优势:

  • Object.defineProperty 支持 IE9+ 浏览器
  • 可处理原始类型的相应,vue3中的 ref
延伸

vue3 中,响应式分引用类型、原始类型。

  • reactive() 仅对引用类型有效,原始类型无效 – 因为 JavaScript 没有可以作用于所有值类型的 “引用” 机制;
  • ref()方法来允许我们创建可以使用任何值类型的响应式,传入参数的值包装为一个带 .value 属性的 ref 对象。

Vue 的响应式系统是通过属性访问进行追踪的,因此我们必须始终保持对该响应式对象的相同引用。

注意:替换一个响应式对象(引用地址 => 原始类型),也需要使用 ref

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key)
      return target[key]
    },
    set(target, key, value) {
      target[key] = value
      trigger(target, key)
    }
  })
}

function ref(value) {
  const refObject = {
    get value() {
      track(refObject, 'value')
      return value
    },
    set value(newValue) {
      value = newValue
      trigger(refObject, 'value')
    }
  }
  return refObject
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Vue2和Vue3响应式原理实现的核心
Vue.js 是一个开源的渐进式 JavaScript 前端框架,主要用于构建用户界面和单页应用程序(SPA)。Vue.js 可以轻松地与其他库或现有项目集成使用,并被认为是开发响应式数据驱动的现代 Web 应用的一种有效方式。
九仞山
2023/10/14
8550
浅谈 JavaScript 数据双向绑定[Proxy/defineProperty]
从 JavaScript 的数据双向绑定(defineProperty、Proxy)开始,谈谈 Vue2 中的数组监听问题。
老猫-Leo
2023/12/11
4910
浅谈 JavaScript 数据双向绑定[Proxy/defineProperty]
02-vue源码分析之 vue3.0为何弃用Object.defineProperty而选择Proxy
在3.0中 双向绑定将会使用Proxy来代替2.x版本的Object.defineProperty,那么我们来看一下Proxy对比defineProperty优势在哪 首先这两种都是基于数据劫持实现的双向绑定
全栈若城
2024/02/29
1420
ES6 系列之 defineProperty 与 proxy
我们或多或少都听过“数据绑定”这个词,“数据绑定”的关键在于监听数据的变化,可是对于这样一个对象:var obj = {value: 1},我们该怎么知道 obj 发生了改变呢?
夜尽天明
2019/07/17
5440
深入理解vue2.x中Object.defineproperty()和vue3.x中Proxy
vue2.x中数据的双向绑定主要通过Object.defineproperty()方法实现,data中的数据改变通过Object.defineProperty()对属性设置set属性,获取通过get属性,Object.defineProperty的作用就是劫持一个对象的属性,通常我们对属性的getter和setter方法进行劫持,在对象的属性发生变化时进行特定的操作。而vue3.x主要是通过proxy实现, proxy在目标对象的外层搭建一层拦截,外界对目标对象的某些操作,必须通过这层拦截。
can4hou6joeng4
2023/11/29
2390
Object.defineProperty 与 Proxy 有什么区别?
大家好,我是前端西瓜哥,今天来看看 Object.defineProperty 和 Proxy 的区别。
前端西瓜哥
2022/12/21
5180
Object.defineProperty 与 Proxy 有什么区别?
为什么采用Proxy重构响应系统 | Vue3源码系列
修改的是程序默认形为,形同于在编程语言层面上做修改,属于元编程(meta programming)
陈大鱼头
2020/09/30
1.1K0
彻底搞懂Object.defineProperty
早在大半年前,掘金某位用户分享的面试题整理中有一题,简述let与const区别,你能自己模拟实现它们吗?,题目意思大概如此,时间久远我也很难找到那篇文章,当时看到此题对于const实现我的想法就是有个writable属性可以定义值是否可以修改,不过也只是脑中一闪,并未细究。
zz_jesse
2021/01/06
1.7K0
彻底搞懂Object.defineProperty
【深入vue】为什么Vue3.0不再使用defineProperty实现数据监听?(修订版)
vue3.0中,响应式数据部分弃用了Object.defineProperty,使用Proxy来代替它。本文将主要通过以下方面来分析为什么vue选择弃用Object.defineProperty。
桃翁
2020/02/26
2.5K0
【图解系列】Object.defineProperty vs Proxy
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
用户9914333
2022/07/22
4730
【图解系列】Object.defineProperty  vs  Proxy
使用 Object.defineProperty 为对象定义属性
目前前端开发中比较流行的两个框架: Angular 和 Vue 都采用了数据双向绑定的技术。 Angular1 中数据双向绑定是通过「脏检测」的方式实现,每当数据发生变更,对所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了变化以及这个变化是否会影响其它数据的变化,然后将变更的数据发送到视图,更新页面展示。
李振
2021/11/26
1.1K0
为什么vue3要选用proxy,好处是什么?
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
hellocoder2029
2022/10/21
6280
聊聊 Object.defineProperty()
如果我们直接为对象添加一个属性,比如 obj.a = 10 我们说 a 是 普通属性,他的值既可以被改变,也可以被删除,还可以被for..in 或 Object,keys 枚举遍历。
mafeifan
2019/06/17
6950
js Object.defineProperty()详解
要修改属性的默认特性,就必须使用 Object.defineProperty()方法 ;在了解Object.defineProperty()之前,需要先明白对象属性的一些特性,明白了这些特性之后,对Object.defineProperty()的学习就会顺利很多了。
IT工作者
2022/05/12
2.6K0
【面试题解】Object.defineProperty 都能 \"define\" 什么?
可以看到,我分别打印了原始对象,修改属性后的对象,添加属性后的对象。如果第二个参数 prop 存在,则是修改属性操作,如果 prop 不存在,则是添加属性操作。
一尾流莺
2022/12/10
3170
【面试题解】Object.defineProperty 都能 \"define\" 什么?
Object.defineProperty方法详解
Object.defineProperty() 方法在 JavaScript 中被用来直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。这个方法允许你精确地控制属性在对象上的行为,包括属性的值、可写性、可枚举性和可配置性。
jack.yang
2025/04/05
1420
自己实现一个VUE响应式--VUE响应式原理
这里的响应式(Reactive)不同于CSS布局的响应式(Responsive), 这里的响应式是指数据和视图的绑定,数据一旦更新,视图会自动更新。下面让我们来看看Vue是怎么实现响应式的,Vue 2.0和Vue 3.0的实现原理还不一样,我们来分开讲。
蒋鹏飞
2020/10/15
6690
自己实现一个VUE响应式--VUE响应式原理
强大的JS方法Object.defineProperty详解及VUE.JS双向绑定原理
我们知道对象是由多个键/值对组成的无序集合。对象当中的属性可以是任意类型的值。我们可以通过构造函数以及字面量的形式来定义对象。
用户1272076
2019/03/26
1.2K0
手写 Vue (二):响应式
提到 Vue 的响应式,通常指的是视图跟随数据的改变而更新。开发上带来的便利是,在需要更新视图呈现时,只需修改视图渲染所需要的数据即可,而不用手动操作DOM。从实现来说,可以分为两个部分:
我是一条小青蛇
2020/12/09
7210
每日一题之Vue数据劫持原理是什么?
定义: 数据劫持,指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。
bb_xiaxia1998
2022/10/06
5360
推荐阅读
相关推荐
Vue2和Vue3响应式原理实现的核心
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档