目录
1、Proxy 对象到底是什么?
2、通过Proxy 对象操作原对象
3、set方法和get方法
4、干预删除行为(对delete obj.prop语句生效)
5、干预prop in obj行为(判断对象是否有某个属性)
6、总结
首页 微信小程序 小程序开发 Proxy 对象的了解及学习

Proxy 对象的了解及学习

Jun 29, 2020 am 10:39 AM
proxy

1、Proxy 对象到底是什么?

Proxy 对象到底是什么呢?Proxy 的意思是 代理,proxy对象的作用是:通过Proxy 创建1个代理对象,然后通过操作代理对象允许你对指定的对象的一些行为进行自定义处理。

Proxy(target,handler); Proxy构造函数接收2个对象,第1个参数就是要处理的对象,第2个参数就是要自定义处理的方法的合集(也就是个对象)。

很抽象?其实就和js中的Object.defineProperty很像(也就是访问器属性,vue2.x的底层就是用它来实现的)。

Object.defineProperty 定义访问器属性,可以对某个属性的读写行为进行控制,在Proxy中也可以做到,而且Proxy更灵活和强大,它能做到很多访问器属性做不到的事情。

比如,监听属性删除事件(delete obj.prop;),in 事件('id' in obj;), apply 调用等。

先来看看,proxy对象有哪些内容。

    var targetObj = {
        id : 1,
        name : 'pxh',
        age : 20,
        school : '小学'
    }
    
    var handler = {};
    
    // 此处,我们先不对targetObj的行为进行干预,所以传个空对象进去即可。
    var proxy = new Proxy(targetObj,handler);
    
    console.log(proxy);
登录后复制

看看打印的proxy是什么鬼,如下图。

9fb2fc2bef33767ca44be7d513f3bd7.png

可以看到,proxy对象中,包含了Handler属性和Target属性和IsRevoked,它们的值分别是我们传入的handler以及 targetObj和false。

这个isRevoked表示是否可撤销,生成可撤销的proxy对象用Proxy.revocable()方法,具体可去MDN查看文档。

2、通过Proxy 对象操作原对象

上面我们创建了1个proxy对象,现在我们尝试通过操作proxy对象来操作原对象,操作proxy对象就和操作原生对象一样即可。(其实是proxy对象内部做了映射。)

    var targetObj = {
        id : 1,
        name : 'pxh',
        age : 20,
        school : '小学'
    }
    
    var handler = {};
    
    // 此处,我们先不对targetObj的行为进行干预,所以传个空对象进去即可。
    var proxy = new Proxy(targetObj,handler);
    
    
    /**
     * 1、读取及修改属性,可以看到原来的对象的属性也被修改了
     */
    console.log(proxy.age);  // 20
    console.log(targetObj.age); // 20
    proxy.age = 22;
    console.log(proxy.age);  // 22
    console.log(targetObj.age); // 22
    
    /**
     * 2、删除proxy对象的属性,影响原来的对象的属性
     */
    console.log(proxy.school);  // 小学
    console.log(targetObj.school); // 小学
    delete proxy.age;
    console.log(proxy.school);  // undefined
    console.log(targetObj.school); // undefined
登录后复制

3、set方法和get方法

好,现在我们可以开始干预原来对象的行为了,具体我们通过实现以下方法达到干预对象行为的目的。

  • handler.apply

  • handler.construct       干预构造函数的new 行为

  • handler.defineProperty  干预对象的数据属性或者访问器属性定义

  • handler.deleteProperty  干预对象的属性删除行为

  • handler.get             干预对象的属性读取行为

  • handler.getOwnProperty  干预对象的属性的特征值

  • handler.has             干预对象的in行为(prop in obj)

  • handler.isExtensible

  • handler.ownKeys

  • handler.set             干预对象的属性设置行为

  • ...

先来干预get行为(属性读取行为)

    var targetObj = {
        id : 1,
        name : 'pxh',
        age : 20,
        school : '小学'
    }
    
    
    var handler = {
        // 定义get方法,get方法可以接收2个参数,分别是原来的对象及属性
        get : function(target,prop){
            console.log(`${prop}属性正在被查看`);
            console.log(targetObj == target); // true
            return target[prop];
        }
    };
    
    var proxy = new Proxy(targetObj,handler);
    
    console.log(proxy.id);
    
    /**
     * 可以看到,打印顺序为:
     *  id属性正在被查看
     *  true
     *  1
     */
登录后复制

接下来把某些属性变为 “私有” ,如不允许读取id属性

定义set方法,不允许修改id,name,age属性

    var targetObj = {
        id : 1,
        name : 'pxh',
        age : 20,
        school : '小学'
    }
    
    
    var handler = {
        // 定义get方法,get方法可以接收2个参数,分别是原来的对象及属性
        get : function(target,prop){
            if(prop == 'id'){
                return undefined;
            }
            return target[prop];
        },
        // 定义set方法,set方法比get多1个参数,那就是该属性修改时的值
        set : function(target,prop,value){
            if(prop == 'id' || prop == 'name' || prop == 'age'){
                console.log(`不允许修改${prop}属性`)
            }else{
                target[prop] = value;
            }
        }
    };
    
    var proxy = new Proxy(targetObj,handler);
    
    /**
     * 修改属性,分别打印
     * 不允许修改id属性
     * 不允许修改name属性
     * 不允许修改age属性
     */
    proxy.id = 2; 
    proxy.name = 'pxh222';
    proxy.age = 23;
    
    proxy.school = '中学'; // 这个无打印
    
    /**
     * 读取属性,可以看到分别打印
     * undefined
     * pxh
     * 20
     * 中学  // 这个没有拦截,因此可以修改
     */
    console.log(proxy.id);
    console.log(proxy.name);
    console.log(proxy.age);
    console.log(proxy.school);
登录后复制

4、干预删除行为(对delete obj.prop语句生效)

同样的,我们对删除对象属性的行为进行干预,不允许删除id,name,age属性。

    var targetObj = {
        id : 1,
        name : 'pxh',
        age : 20,
        school : '小学'
    }
    
    var handler = {
        // 在handler中定义get方法,get方法可以接收2个参数,分别是原来的对象及属性
        get : function(target,prop){
            if(prop == 'id'){
                return undefined;
            }
            return target[prop];
        },
        // set方法比get多1个参数,那就是该属性修改时的值
        set : function(target,prop,value){
            if(prop == 'id' || prop == 'name' || prop == 'age'){
                console.log(`不允许修改${prop}属性`)
            }else{
                target[prop] = value;
            }
        },
        /**
         * 这个方法要求返回个boolean值,表示是否删除成功
         * 如果返回的值不是boolean值,则会进行类型转换成boolean值再返回
         */
        deleteProperty : function(target,prop){
            if(prop == 'id' || prop == 'name' || prop == 'age'){
                console.log(`不允许删除${prop}属性`);
                return false;
            }else{
                delete target[prop];
                return true;
            }
        }
    };
    
    var proxy = new Proxy(targetObj,handler);
    /**
     * 尝试删除id属性,可以看到打印顺序为:
     * 不允许删除id属性
     * false
     */
    console.log(delete proxy.id);
    
    /**
     * 删除school属性,可以看到打印
     * true
     * undefined
     */
    console.log(delete proxy.school);
    console.log(proxy.school);
登录后复制

5、干预prop in obj行为(判断对象是否有某个属性)

上面我们不允许获取对象的id值,也不可以修改和删除,现在我们把它隐藏掉。

    var targetObj = {
        id : 1,
        name : 'pxh',
        age : 20,
        school : '小学'
    }
    
    var handler = {
        // 在handler中定义get方法,get方法可以接收2个参数,分别是原来的对象及属性
        get : function(target,prop){
            if(prop == 'id'){
                return undefined;
            }
            return target[prop];
        },
        // set方法比get多1个参数,那就是该属性修改时的值
        set : function(target,prop,value){
            if(prop == 'id' || prop == 'name' || prop == 'age'){
                console.log(`不允许修改${prop}属性`)
            }else{
                target[prop] = value;
            }
        },
        /**
         * 这个方法要求返回个boolean值,表示是否删除成功
         * 如果返回的值不是boolean值,则会进行类型转换成boolean值再返回
         */
        deleteProperty : function(target,prop){
            if(prop == 'id' || prop == 'name' || prop == 'age'){
                console.log(`不允许删除${prop}属性`);
                return false;
            }else{
                delete target[prop];
                return true;
            }
        },
        /**
         * 通过has 方法来控制,返回值也是个boolean,表示对象是否拥有某个属性
         * 如果返回的值不是boolean值,则会进行类型转换成boolean值再返回
         */
        has : function(target,prop){
            if(prop == 'id'){
                return false
            }else{
                return prop in target;
            }
        }
    };
    
    var proxy = new Proxy(targetObj,handler);
    console.log('id' in proxy); // false
    console.log('name' in proxy); // true
登录后复制

6、总结

同样的,proxy还能干预对象的行为还有很多,这里就不一一介绍了。感兴趣戳MDN文档

推荐教程:《微信小程序

以上是Proxy 对象的了解及学习的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Nginx Proxy Manager配置解析与优化 Nginx Proxy Manager配置解析与优化 Sep 26, 2023 am 09:24 AM

NginxProxyManager配置解析与优化概述:NginxProxyManager是一个基于Nginx的反向代理管理工具,可以帮助我们方便地配置和管理反向代理服务器。在使用NginxProxyManager的过程中,我们可以通过对其配置进行解析与优化,提高服务器的性能与安全性。配置解析:配置文件位置和结构:NginxProxyManag

nginx中怎么配置使用proxy protocol协议 nginx中怎么配置使用proxy protocol协议 May 18, 2023 am 08:47 AM

proxyprotocol在nginx中应用我们知道nginx是一个web服务器和代理服务器,它一般工作在proxyserver或者负载均衡软件(Haproxy,AmazonElasticLoadBalancer(ELB)的后面。客户端首先请求proxyserver或者LSB负载均衡软件,然后再到nginx进行真实的web访问。因为经过了多层软件,所以客户端的一些信息比如ip地址,端口号等可能就会被隐藏,这对于我们问题分析,数据统计都是不利的。因为对于nginx来说,我们希望能够获得真实的客户端

Nginx Proxy Manager下的容器与微服务的部署策略 Nginx Proxy Manager下的容器与微服务的部署策略 Sep 27, 2023 pm 01:06 PM

NginxProxyManager下的容器与微服务的部署策略,需要具体代码示例摘要:随着微服务架构的流行,容器化技术成为了现代软件开发的重要组成部分。而在微服务架构中,NginxProxyManager扮演着很重要的角色,用于管理和代理微服务的流量。本文将介绍如何使用NginxProxyManager来部署和管理容器化的微服务,并提供相关的代码示

如何使用Nginx Proxy Manager实现多台服务器的负载均衡 如何使用Nginx Proxy Manager实现多台服务器的负载均衡 Sep 27, 2023 pm 09:42 PM

如何使用NginxProxyManager实现多台服务器的负载均衡NginxProxyManager是一个基于Nginx开发的代理服务器管理工具,它提供了一个简单易用的Web界面,可以方便地配置和管理Nginx代理服务器。在实际应用中,我们经常需要将请求分发到多台服务器上,以实现负载均衡和提高系统的性能和可用性。本文将介绍如何使用NginxProx

Nginx Proxy Manager教程:快速入门指南 Nginx Proxy Manager教程:快速入门指南 Sep 27, 2023 pm 05:39 PM

NginxProxyManager教程:快速入门指南,需要具体代码示例引言:随着网络技术的发展,代理服务器成为我们日常使用互联网的一部分。NginxProxyManager是一个基于Nginx的代理服务器管理平台,可以帮助我们快速建立和管理代理服务器。本篇文章将为大家介绍NginxProxyManager的快速入门指南,以及一些具体的代码示例。一

Nginx Proxy Manager的日志分析与监控 Nginx Proxy Manager的日志分析与监控 Sep 26, 2023 am 09:21 AM

NginxProxyManager的日志分析与监控,需要具体代码示例引言:NginxProxyManager是一个基于Nginx的代理服务器管理工具,它提供了一种简单而有效的方法来管理和监控代理服务器。在实际运行中,我们常常需要对NginxProxyManager的日志进行分析和监控,以便及时发现潜在的问题或优化性能。本文将介绍如何使用一些常用的

Nginx Proxy Manager实现HTTP请求的缓存加速 Nginx Proxy Manager实现HTTP请求的缓存加速 Sep 26, 2023 am 10:53 AM

NginxProxyManager是一个用于管理Nginx代理服务器的工具,通过使用它可以实现HTTP请求的缓存加速。下面将详细介绍如何使用NginxProxyManager实现缓存加速,并提供具体的代码示例。一、安装和配置NginxProxyManager安装NginxProxyManager:$npminstall-g@nginx

Nginx Proxy Manager原理与实践:优化网站性能的关键 Nginx Proxy Manager原理与实践:优化网站性能的关键 Sep 26, 2023 am 11:06 AM

NginxProxyManager原理与实践:优化网站性能的关键,需要具体代码示例引言:在当今互联网时代,网站性能对于用户体验和搜索引擎优化至关重要。为了提高网站的性能,一个有效的方法是使用Nginx作为反向代理服务器来管理和分发流量。本文将介绍NginxProxyManager的原理与实践,展示如何通过NginxProxyManager优化网站

See all articles