Comprendre et apprendre les objets proxy

hzc
Libérer: 2020-06-29 10:39:44
avant
2970 Les gens l'ont consulté

1. Qu'est-ce que l'objet Proxy exactement ?

Qu'est-ce que l'objet Proxy exactement ? Proxy signifie proxy. La fonction de l'objet proxy est de créer un objet proxy via Proxy, puis d'exploiter l'objet proxy pour vous permettre de personnaliser certains comportements de l'objet spécifié.

Proxy(target,handler); Le constructeur Proxy reçoit 2 objets. Le premier paramètre est l'objet à traiter et le deuxième paramètre est la collection de méthodes à personnaliser (c'est-à-dire un objet).

Très abstrait ? En fait, il est très similaire à Object.defineProperty dans js (c'est-à-dire la propriété accesseur, qui est utilisée pour implémenter la couche inférieure de vue2.x).

Object.defineProperty définit les propriétés d'accesseur, qui peuvent contrôler le comportement de lecture et d'écriture d'une certaine propriété. Cela peut également être fait dans Proxy, et Proxy est plus flexible et plus puissant. . Des choses qui ne peuvent pas être accomplies.

Par exemple, écoutez les événements de suppression d'attribut (delete obj.prop;), dans les événements (« id » dans obj;), appliquez des appels, etc.

Jetons d’abord un coup d’œil à ce que contient l’objet proxy.

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

Regardez le proxy imprimé, comme indiqué ci-dessous.

Comprendre et apprendre les objets proxy

Comme vous pouvez le voir, l'objet proxy contient l'attribut Handler, l'attribut Target et IsRevoked. Leurs valeurs sont respectivement le gestionnaire que nous avons transmis, targetObj et false.

This isRevoked indique s'il est révocable. Utilisez la méthode Proxy.revocable() pour générer un objet proxy révocable. Pour plus de détails, vous pouvez accéder à MDN pour consulter la documentation.

2. Faites fonctionner l'objet d'origine via l'objet proxy

Ci-dessus, nous avons créé un objet proxy. Nous essayons maintenant d'exploiter l'objet d'origine en exploitant l'objet proxy. comme l'exploitation de l'objet natif. (En fait, l'objet proxy est mappé en interne.)

    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
Copier après la connexion

3. Définir la méthode et obtenir la méthode

D'accord, nous pouvons maintenant commencer à interférer avec le comportement de l'objet d'origine. mettre en œuvre les méthodes suivantes Atteindre l'objectif d'intervenir sur le comportement de la cible.

  • handler.apply

  • handler.construct Intervenir dans le nouveau comportement du constructeur

  • handler.defineProperty Intervient sur la définition de l'attribut de données ou de l'attribut d'accesseur de l'objet

  • handler.deleteProperty Intervient sur le comportement de suppression d'attribut de l'objet

  • handler .get Intervient dans le comportement de lecture de l'attribut de l'objet

  • handler.getOwnProperty Intervient sur la valeur caractéristique de l'attribut de l'objet

  • handler.has Intervient dans le dans le comportement (prop dans obj)

  • handler.isExtensible

  • handler.ownKeys

  • handler

  • ...

Intervenez d'abord dans le comportement get (comportement de lecture des attributs)

    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
     */
Copier après la connexion

Ensuite, modifiez certains attributs en " Private", par exemple, il n'est pas autorisé de lire l'attribut id

et de définir la méthode set, et il n'est pas autorisé de modifier les attributs id, name et 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);
Copier après la connexion

4 . Intervenons dans le comportement de suppression (efficace pour l'instruction delete obj.prop)

De même, nous intervenons dans le comportement de suppression des attributs d'objet et n'autorisons pas la suppression des attributs id, name et 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);
Copier après la connexion

5. Intervenir dans prop dans le comportement obj (déterminer si l'objet a un certain attribut)

Ci-dessus, nous ne sommes pas autorisés à obtenir la valeur id de l'objet, ni à modifier ou supprimez-le. Maintenant, nous le mettons. Cachez-le.

    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
Copier après la connexion

6. Résumé

De même, il existe de nombreuses façons dont le proxy peut interférer avec le comportement de l'objet, je ne les présenterai donc pas une par une ici. Si vous êtes intéressé, cliquez sur le document MDN

Tutoriel recommandé : "WeChat Mini Program"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:jianshu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!