JavaScript Object.defineProperty与proxy代理模式的使用详细分析

目录
  • 1. Object.defineProperty
  • 2. Object.defineProperties
  • 3. proxy
  • 代理模式
  • 总结

1. Object.defineProperty

const obj = {};
Object.defineProperty(obj,prop,descript);
  • 参数 obj 要定义属性的对象
  • prop 要定义的属性
  • descript 属性描述符

返回值:被传递给函数的对象

descript接收一个对象作为配置:

  • writable

属性是否可写 默认值fasle

  • value

属性的值 默认值false

  • enumerable

属性是否可枚举,关系到能否被for…in、Object.keys()以及in关键字遍 默认值false

  • configurable 属性是否可以被defineProperty定义
  • set setter函数
  • get getter函数

使用defineProperty定义的属性descript默认值全为false

const obj = {};
obj.name = 'a';
//等同于
Object.defineProperty(obj,'name',{
  configurable: true,
  value: 'a',
  writable: true,
  enumerable: true,
});
conts obj1 = Object.defineProperty({},'name',{value: 'jack'});
//等同于
Object.defineProperty({},'name',{
  value: 'jack',
  enumerable: false,
  writable: false,
  configurable: fasle,
})

value和writable不能和setter与getter一起使用

       const obj = Object.defineProperty({},name,{
        writable:true,
        value: 'jack',
        set:function(newVal){
          return newVal;
        },
        get:function(val){
          return val;
        }
       });

执行上面的代码出现异常:

Uncaught TypeError: property descriptors must not specify a value or be writable when a getter or setter has been specified.

也就是说我们使用writable和value或者set和get去定义属性的读写,不能混合使用

      const obj = Object.defineProperty({},name,{
        writable:true,
       });
       const obj1 = Object.defineProperty({},name,{
        set:function(newVal){
          return newVal;
        },
        get:function(val){
          return val;
        }
       });
       obj.name = 'ian';
       obj1.name = 'jack';

2. Object.defineProperties

Object.defineProperties用法与Object.definePropert一致,可以同时定义多个属性

      const obj = Object.defineProperties(obj, {
        name: {
          configurable: true,
          enumerable: true,
          writable: true,
          value: 'ian',
        },
        gender: {
          writable: false,
          value: 'male'
        },
        age: {
          set: function (val) { return val },
          set: function (val) { return val },
        }
      });

3. proxy

proxy的功能是代理对象,用于拦截对象的基本操作和自定义,与Object.defineProperty类似,区别是proxy代理整个对象,defineProperty只能代理某个属性。

语法

const obj = {};
const proxyObj = new Proxy({obj, handler});

handler 对象的方法:

  • setProptotypeOf()

Object.setPropertyOf的捕捉器

  • isExtensible()

Object.isExtensible的捕捉器

  • preventExtensions()

Object.preventExtensions方法的捕捉器

  • getOwnPropertyDescritor()

Object.getOwnPropertyDescriptor方法的捕捉器

  • defineProperty()

Object.definePropert方法的捕捉器

  • has()

in操作符的捕捉器

  • deleteProperty()

delete操作符的捕捉器

  • set

属性设置操作的捕捉器

  • get

属性获取操作的捕捉器

  • onwKeys

Object.getOwnPropertyNames和Object.getOwnSymbos的捕捉器

  • apply

函数调用操作的捕捉器

  • constructor

new操作符的捕捉器

使用get捕捉器

    const obj = { name: 'ian', age: 21 };
    const proxyObj = new Proxy(obj, {
      get: function (obj, prop) {
        return prop in obj ? obj[prop] : 'prop not existent';
      },
    });
    console.log(proxyObj.gender); //prop not existent

使用set捕捉器验证属性值

      const obj = { name: 'ian' };
      const proxyObj = new Proxy(obj, {
        set: function (obj, prop, value) {
          if (prop === 'age') {
            if (typeof value !== 'number') {
              throw new TypeError('The age is not Integer');
            };
            if (value > 200) {
              throw new RangeError('The age is not invalid');
            };
          }
          obj[prop] = value;
          //标识修改成功
          return true;
        }
      });
      proxyObj.gender = 'male'; //male
      proxyObj.age = '二十'; // Uncaught TypeError: The age is not Integer
      proxyObj.age = 201;  //Uncaught RangeError: The age is not invalid
      proxyObj.age = 20; //20

捕获new操作符

    function Person(name) {
      this.name = name;
    };
    const ProxyPerson = new Proxy(Person, {
      construct: function (target, args) {
        //使用原本的构造函数
        return new Person(...args);
      }
    })
    var jack = new ProxyPerson('jack');
    console.log(jack);//Object { name: "jack" }

捕获函数调用

    //执行原本的函数
    const proxyFoo = new Proxy(log,{
      apply:function(target,that,args){
        target(args);
      }
    });
    proxyFoo('foo'); //foo
    //自定义函数
    const proxyFoo1 = new Proxy(log, {
    apply: function (target, that, args) {
      //将log改成alert执行
      alert(args);
    }
   });
    proxyFoo1('foo'); //foo

代理模式

当我们去访问一个数据的时候,不直接去访问数据,而是通过代理(Proxy)作为一个中间者替我们去获取和设置数据,在proxy层可以做一些访问控制等, 例如进行数据的校验数,据合法后再设置给原数据,起到一个保护和校验的功能。常见的代理模式有:

  • 保护代理

给被调用者提供访问控制,确认调用者的权限

  • 远程代理
  • 虚拟代理

用来代替巨大的对象,确保在需要的时候才被创建

  • 智能引用代理

总结

  • proxy是浏览器提供的代理方式,相比较defineProperty来说Proxy更加灵活,能代理对象的多个属性
  • proxy还能捕捉和拦截数组、函数、构造器、以及Object的一些方法和操作符

到此这篇关于JavaScript Object.defineProperty与proxy代理模式的使用详细分析的文章就介绍到这了,更多相关JS Object.defineProperty与proxy内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JS代理对象Proxy初体验简单的数据驱动视图

    目录 引言 Proxy对象是什么 使用Proxy写一个简单的数据驱动视图 引言 上大学的时候,最流行的框架是JQuery,它是事件驱动类型的,也就是说,当一个数据与DOM的某个内容相关联的时候,我需要在这个数据改变之后,去操作DOM来进行同步: <div id="data">数据</div> var data = "数据" // 通过某种事件数据发生了变化 data = "新数据" $("#data")

  • Javascript对象及Proxy工作原理详解

    正文 这一章其实算是javascript的科普文章,其实这本书的读者一般都不会是入门者,因此按道理说应该不需要再科普才对.但是作者依旧安排了这一章,证明就是这一章内容与我们以为的对象不一样. Javascript中一切皆对象 这一句话大家应该耳熟能详,对于常规的字面量对象,和new出来的对象,大家应该都能分辨 const str = '' const str2 = new String() const obj = {} const obj2 = Object.create() 但是根据ECMA,

  • JS带你深入领略Proxy的世界

    1. Proxy 的基本结构 Proxy 的基本使用方式: /** * target: 表示要代理的目标,可以是object, array, function类型 * handler: 是一个对象,可以编写各种代理的方法 */ const proxy = new Proxy(target, handler); 例如我们想要代理一个对象,可以通过设置 get 和 set 方法来代理获取和设置数据的操作: const person = { name: 'wenzi', age: 20, }; con

  • JavaScript的Object.defineProperty详解

    =与Object.defineProperty 为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty()定义.如下: // 示例1 var obj = {}; // 直接使用=赋值 obj.a = 1; // 使用Object.defineProperty定义 Object.defineProperty(obj, "b", { value: 2 }); console.log(obj) // 打印"{a:

  • 深入浅出JS的Object.defineProperty()

    目录 前言 对象的定义与赋值 Object.defineProperty()语法说明 属性的特性以及内部属性 属性描述符 数据描述符 --特有的两个属性(value,writable) 存取描述符 --是由一对 getter.setter 函数功能来描述的属性 数据描述符和存取描述均具有以下描述符 configrable 代码片段分析 enumerable 代码片段分析 不变性 对象常量 对象常量 密封 属性定义和属性赋值 属性定义,通过Object.defineProperty()形式 属性赋

  • JavaScript的Proxy对象详解

    目录 一.Proxy 是什么? 二.怎么用? 1.使用 Proxy 的简单实例 2.目标对象被正确修改 3.使用 set handler 做数据验证 4.扩展构造函数 总结 一.Proxy 是什么? Proxy 对象用于拦截并修改目标对象的指定操作. // 语法 const p = new Proxy(target, handler) target :目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理). handler :以函数作为属性的对象,实现拦截和自定义操作. 二.怎么用

  • JavaScript Object.defineProperty与proxy代理模式的使用详细分析

    目录 1. Object.defineProperty 2. Object.defineProperties 3. proxy 代理模式 总结 1. Object.defineProperty const obj = {}; Object.defineProperty(obj,prop,descript); 参数 obj 要定义属性的对象 prop 要定义的属性 descript 属性描述符 返回值:被传递给函数的对象 descript接收一个对象作为配置: writable 属性是否可写 默认

  • 解析proxy代理模式在Ruby设计模式开发中的运用

    代理模式 Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上.在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层.如下图: 比如说C和A不在一个服务器上,A要频繁的调用C,我们可以在A上做一个代理类Proxy,把访问C的工作交给Proxy,这样对于A来说,就好像在直接访问C的对

  • vue数据监听解析Object.defineProperty与Proxy区别

    目录 前言 Object.defineProperty 与 Proxy 的区别 在使用上的差异 总结与思考 前言 总能深深感觉到自己能力有限,写这篇文章的目的纯粹是因为发现在实际工作中,和一些小伙伴交流时发现,虽然有些小伙伴大概知道 vue2 与 vue3 的区别,但并没有去进一步思考一些深一点的东西.尽管能力有限,但想着自己在起步时候的艰难,就想着分享一下自己的一些看法,虽然不一定有多深入,但能引起大家的一些思考也是好的. Object.defineProperty 与 Proxy 的区别 其

  • mysql中binlog_format模式与配置详细分析

    mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR).对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED. ① STATEMENT模式(SBR) 每一条会修改数据的sql语句会记录到binlog中.优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binl

  • 详解设计模式中的proxy代理模式及在Java程序中的实现

    一.代理模式定义 给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象. 著名的代理模式的例子就是引用计数(reference counting): 当需要一个复杂对象的多份副本时, 代理模式可以结合享元模式以减少存储器的用量.典型做法是创建一个复杂对象以及多个代理者, 每个代理者会引用到原本的对象.而作用在代理者的运算会转送到原本对象.一旦所有的代理者都不存在时, 复杂对象会被移除. 要理解代理模式很简单,其实生活当中就存在代理

  • C++设计模式编程中proxy代理模式的使用实例

    代理模式典型的结构图为: 实际上,代理模式的想法非常简单. 代理模式的实现: 完整代码示例(code):代理模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 VC 6.0 下测试运行). 代码片断 1:Proxy.h //Proxy.h #ifndef _PROXY_H_ #define _PROXY_H_ class Subject{ public: virtual ~Subject(); virtual void Request() =

  • php设计模式 Proxy (代理模式)

    代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,都是通过代理来完成他的销售业务.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,具体红酒工厂在那里,客户不用关心,代理会帮他处理. 代理模式,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用. 代理模式涉及的角色: 抽象主题角色,声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替. 代理主题角色,含有真实主题的引用,从而可以在任何时候操

  • JavaScript的设计模式经典之代理模式

     一.代理模式概念 说明:顾名思义就是用一个类来代替另一个类来执行方法功能,这个模式跟装饰模式有点相似,不一样的是,代理模式是代替客户初始化被代理对象类,而装饰模式采用接口或初装饰者参数引用的方式来执行的. 解释:房屋中介,可以代理帮助卖家把房子卖给买家,这中间卖家说要卖的价钱就可以了,买家也可以提出自己要买的房型,中介可以帮忙处理中间环节.最后达成买卖.中介可以同时代理很多房屋买卖,并且可以代理租房事宜. 二.代理模式的作用和注意事项 模式作用: 1.远程代理(一个对象将不同空间的对象进行局部

  • Javascript访问html页面的控件的方法详细分析第1/2页

    下面切入正题:    访问控件的主要对象是:document对象.分别对应当前文档所有的(子对象)个人观点.并且已经提供的几个主要方法来访问对象. 1.       document.getElementById 2.       document.getElementsByName  3           document.getElementsByTagName 4           document.all 下面我主要谈谈以上几个方法的具体用法:   一.首先我来谈谈document.

随机推荐