目錄
1、Proxy 物件到底是什麼?
2、透過Proxy 物件操作原對象
3、set方法和get方法
首頁 微信小程式 小程式開發 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是什麼鬼,如下圖。

Proxy 物件的了解與學習

可以看到,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 05:39 PM

NginxProxyManager教學:快速入門指南,需要具體程式碼範例引言:隨著網路技術的發展,代理伺服器成為我們日常使用網路的一部分。 NginxProxyManager是一個基於Nginx的代理伺服器管理平台,可以幫助我們快速建立和管理代理伺服器。本篇文章將為大家介紹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 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