【javaScript】Proxy与Object.defineProperty的区别

这篇具有很好参考价值的文章主要介绍了【javaScript】Proxy与Object.defineProperty的区别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


【javaScript】Proxy与Object.defineProperty的区别

Proxy和Object.defineProperty都是JavaScript中用于实现对象属性拦截和代理的机制,但它们在功能和应用方面有一些区别。

功能方面的区别:

Object.defineProperty:它是ES5引入的属性定义方法,通过直接定义对象属性的特性(如可枚举性、可写性等),可以拦截属性的读取、写入和删除操作。但它只能拦截对象的属性访问,对于对象的整体操作(如对整个对象的赋值或属性遍历)并不会被拦截

Proxy:它是ES6引入的代理机制,可以对整个对象进行代理,拦截对象的各种操作,包括属性访问、赋值、删除、函数调用等。通过在代理对象上定义各种"陷阱"(trap)方法,可以自定义拦截行为,实现更细粒度的对象操作控制。

比如:

Object.defineProperty对整个对象进行赋值,不会触发set拦截

const obj = {};

Object.defineProperty(obj, 'name', {
  get() {
    console.log('访问name属性');
    return 'John';
  },
  set(value) {
    console.log('设置name属性');
    obj._name = value;
  }
});

// 访问name属性,触发get拦截
console.log(obj.name); // 输出: "访问name属性" 和 "John"

// 设置name属性,触发set拦截
obj.name = 'Alice'; // 输出: "设置name属性"

// 对整个对象进行赋值,不会触发set拦截
obj = { age: 25 }; // 抛出TypeError: Assignment to constant variable.

输出如下图所示:

【javaScript】Proxy与Object.defineProperty的区别

Object.defineProperty对整个对象进行遍历,不会触发get拦截

var obj = {};

Object.defineProperty(obj, 'name', {
  get() {
    console.log('访问name属性');
    return 'John';
  },
  set(value) {
    console.log('设置name属性');
    obj._name = value;
  }
});

// 访问name属性,触发get拦截
console.log(obj.name); // 输出: "访问name属性" 和 "John"

// 设置name属性,触发set拦截
obj.name = 'Alice'; // 输出: "设置name属性"

// 对整个对象进行赋值,不会触发set拦截
obj = { name:"李四" }; 

输出结果如下:

【javaScript】Proxy与Object.defineProperty的区别文章来源地址https://www.toymoban.com/news/detail-482687.html

Proxy自定义拦截行为

const user = {
  name: 'John',
  age: 25,
};

const protectedUser = new Proxy(user, {
  set(target, property, value) {
    if (property === 'age') {
      throw new Error('age属性不可被修改');
    }

    return Reflect.set(target, property, value);
  },
  deleteProperty(target, property) {
    if (property === 'name') {
      throw new Error('name属性不可被删除');
    }

    return Reflect.deleteProperty(target, property);
  },
});

console.log(protectedUser.name); // 输出: "John"

protectedUser.name = 'Alice'; // 不会抛出错误,属性赋值成功

console.log(protectedUser.name); // 输出: "Alice"

protectedUser.age = 30; // 抛出错误,无法修改age属性

delete protectedUser.name; // 抛出错误,无法删除name属性

Proxy的优缺点

优点:

  • 更全面的拦截能力:Proxy可以拦截对象的更多操作,包括对属性的读取、赋值、删除等,以及函数的调用等,提供了更细粒度的拦截控制。
  • 可变性控制:Proxy可以用于控制对象的可变性,例如可以禁止对某些属性进行赋值或删除,从而实现更严格的对象保护和约束。

缺点

  • 兼容性问题:Proxy是ES6引入的新特性,旧版本的JavaScript环境可能不支持Proxy,因此在一些特定的环境或需求下,使用Proxy可能会导致兼容性问题。
  • 性能开销:相比Object.defineProperty,Proxy的拦截机制更为复杂,因此在某些情况下可能会引入一定的性能开销。但对于大多数应用场景来说,这种开销可以忽略不计。

到了这里,关于【javaScript】Proxy与Object.defineProperty的区别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详解vue中的Object.defineProperty

       如果想要age遍历的话 就设置属性 打印出来 发现有可以枚举的属性age  参考课程: 011_尚硅谷Vue技术_Object.defineProperty_哔哩哔哩_bilibili   // 1.Vue中的数据代理:     //    通过Vm对象来代理data对象中属性的操作(读/写)     // 2.Vue中数据代理的好处:     //   更加方便的

    2024年02月04日
    浏览(41)
  • 使用object.defineProperty来更新数据示例

    vue+element UI 第001个 查看专栏目录: 按照VUE知识点 ------ 按照element UI知识点 echarts,openlayers,cesium,leaflet,mapbox,d3,canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操

    2024年02月06日
    浏览(30)
  • Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

    定义: Object.defineProperty()  方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象 为什么能实现响应式 通过 defineProperty  两个属性, get 及 set get 属性的 getter 函数,当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 th

    2024年03月09日
    浏览(64)
  • js通过Object.defineProperty() 定义和控制对象属性

    用于给一个对象定义一个新属性或是修改某个现有属性,并返回此对象。 Object.defineProperty(obj,prop,descriptor)  它接收 3 个参数,第 1 个是要定义属性的对象;第 2 个是要定义或修改的属性的属性名或 Symbol;第 3 个是对该属性的描述,称之为属性描述符,为一个对象,可以拥有

    2024年03月09日
    浏览(52)
  • 深入理解JavaScript中的Proxy代理

    JavaScript中的Proxy代理是ES6中引入的一项强大功能,它允许我们拦截、修改和自定义对象的底层操作。通过使用Proxy,我们可以在对象的属性读取、赋值、函数调用等操作之前或之后执行自定义的行为。在本文中,我们将深入探讨Proxy代理的各种用法和功能。 Proxy是JavaScript的一

    2024年02月07日
    浏览(41)
  • 解决 JavaScript 输出为 [object Object] 的问题

    🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,计算机系列(火速更新中) 💭 格言:种一棵树最好的时间是十年前,其次是现在 🏡动动小手,点个关注不迷路,感

    2024年02月04日
    浏览(41)
  • JavaScript如何解决返回[object Promise]

    当使用JavaScript中的Promise时,当您尝试访问Promise的值时,您可能会看到返回值为 [object Promise] 的情况。这是因为Promise是一种异步操作,它不能立即返回结果,而是需要等待操作完成后返回结果。 要访问Promise的值,您需要使用Promise的then()方法,该方法接受一个回调函数作为参

    2024年02月12日
    浏览(37)
  • iOS问题记录 - type argument ‘nw_proxy_config_t‘ is neither an Objective-C object nor a block type

    升级Xcode 15后,意料之中,项目又遇到了问题。 Xcode: 15.0 CocoaPods: 1.12.1 flutter_inappwebview: 6.0.0-beta.24+1 Flutter项目在Xcode 15上编译时报错: 从报错信息看,是因为 nw_proxy_config_t 的类型不对导致的,错误发生在 flutter_inappwebview 库用到的 WebKit.framework 中,初步猜测可能是有什么新的

    2024年02月08日
    浏览(43)
  • Object.setPrototypeOf 与 Object.create() 的区别

    在讲之前,我们先回顾下创建对象的几种方式,并且 Object 、 new Object() 和 Object.create 的区别 ①:字面量方式创建对象 ②:构造函数式创建对象 ③: Objecr.create 创建对象 第一和第二种本质上没任何区别,只是简化写法,说下第二种和第三种的区别: new Object() 的过程中会继承

    2023年04月09日
    浏览(26)
  • 【ES6】 JavaScript 中的Object.assign

    Object.assign() 是 JavaScript 中的一个方法,它用于复制源对象的所有可枚举属性到目标对象。该方法会返回目标对象。 这是其基本用法: 在这个例子中,source 对象的所有可枚举属性都被复制到了 target 对象。 需要注意的是,Object.assign() 是浅复制(shallow copy),意味着如果源对

    2024年02月10日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包