Maison >interface Web >js tutoriel >Qu'est-ce que le proxy dans ES6 ? Analyse détaillée du proxy

Qu'est-ce que le proxy dans ES6 ? Analyse détaillée du proxy

不言
不言original
2018-09-27 16:21:393541parcourir

Le contenu de cet article porte sur qu'est-ce que Proxy dans ES6 ? L'analyse détaillée de Proxy a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'elle vous sera utile.

proxy signifie proxy en chinois. Le mot a des significations similaires dans d’autres langages de programmation.

Qu'est-ce que c'est

Le proxy est un constructeur. La caractéristique typique des constructeurs en js est que la première lettre est en majuscule. Nous créons des objets dans le nouveau format Proxy (objet original, {proxy list}). L'objet créé est appelé un objet proxy.
C'est-à-dire :

Objet proxy = nouveau proxy (objet original, {liste proxy})

La raison pour laquelle un tel objet proxy supplémentaire est généré est que l'objet d'origine peut être conservé inchangé. Ajoutez de nouvelles fonctions à l'objet proxy ou modifiez certaines fonctions. L'objet d'origine peut être restauré au moment opportun. Il peut être comparé et compris avec le modèle d'agent dans les modèles de conception.

Format d'utilisation

var obj;
var proxyObj = new Proxy(obj, {
    对obj的操作1: 函数1,
    对obj的操作2: 函数2,
    ...
    
})

Exemple de démarrage

Démonstration de base du proxy

var obj = {name:'fan',age:34}
console.info(obj.name)

var proxyObj = new Proxy(obj,{
    get:function(target,key,receiver){console.info(target,key,receiver); return 'no'}
})

console.info(proxyObj.name) 
console.info(proxyObj.abc)

Expliqué comme suit :

  • L'objet proxxy est un nouvel objet créé à partir de l'objet obj.

  • proxyObj.name doit obtenir l'attribut name de l'objet proxy. .操作符会自动去调用get()方法. C'est très important, 在js中,对象是属性的无序集合。对象只有属性,其他什么都没有. Et on parle souvent d'appeler une certaine méthode d'un objet : par exemple, la méthode sort de l'objet tableau arr : arr.sort(), où sort est aussi un attribut de l'objet arr. (plus strictement, le tri est l'attribut arr.__proto__ de cet objet), par rapport à l'attribut de longueur, la valeur de l'attribut de tri est une fonction, donc ajoutez () après pour exécuter cette fonction, et la valeur de l'attribut de longueur est une valeur numérique, il n'est donc pas nécessaire d'ajouter () pour l'utiliser directement. Encore une fois : 对象的.操作,会自动去调用get. Bien sûr, nous ne nous en rendons pas compte lorsque nous l’utilisons habituellement.

  • Dans le deuxième paramètre du nouveau proxy, la méthode get est clairement définie : lors de l'accès à un attribut de proxyObj, les valeurs de la cible, de la clé et du récepteur sont affichées, et non est renvoyé uniformément. Ainsi, proxyObj.name et proxyObj.abc obtiendront le non.

En écrivant ceci, quelle est, selon vous, la relation entre l'objet d'origine et l'objet proxy ? Pourquoi s'appelle-t-on 代理 ?

Comprendre le rôle d'un agent

L'agent peut être compris comme l'agent de la célébrité.

外界 <----> 原对象;
外界 <----> 代理对象 <------> 原对象;

Prenons le code ci-dessus comme exemple pour améliorer les exigences : si quelqu'un demande le nom de l'objet, dites-le directement à la personne si quelqu'un demande l'âge de l'objet, renvoyez l'âge 5 ans plus jeune ;

var obj = {name:'fan',age:34}
console.info(obj.age)           // 34
var proxyObj = new Proxy(obj,{
    get:function(target,key,receiver){
        console.info(target === obj);           //true
        console.info(receiver === proxyObj);    //true
        if('age' === key){
            return target[key] - 5;
        }
        else{
            return target[key]
        }
    }
})

console.info(proxyObj.age)  // 34- 5 = 29

s'explique comme suit :

  • Les trois paramètres de la fonction get : cible, clé, récepteur. target est l'objet d'origine j, clés est le nom de l'attribut actuel ; le récepteur est l'objet proxy. Vous pouvez effectuer n’importe quel traitement personnalisé dans la méthode get.

La relation entre l'objet proxy et l'objet d'origine

var arr = [2,1]
var proxyArr = new Proxy(arr,{} )
proxyArr.push(3);
console.info(arr) // [2,1,3]
console.info(arr === proxyArr) // false
arr.sort();
console.info(proxyArr[0]) // 1

Dans le code ci-dessus, cet objet proxy n'effectue aucune opération particulière. Il est entendu que les managers de célébrités sont passifs dans leur travail : transmettre les informations du monde extérieur aux célébrités elles-mêmes. Par conséquent, les opérations effectuées sur proxyArr affecteront directement arr.

De même, les opérations sur arr affecteront également proxyArr.
Mais attention : proxyArr et arr sont deux objets différents : arr !== proxyArr.

Vous y réfléchirez peut-être : pourquoi proxyArr peut-il utiliser directement la méthode push ? La raison est :

proxyArr.__proto__ === arr.__proto__ === Array.prototype

La raison pour laquelle l'équation précédente est vraie est déterminée par le gène du nouveau proxy : l'objet d'origine est proxy.

Liste des proxys

Dans le deuxième paramètre du nouveau proxy, les attributs de proxy qui peuvent être définis sont les suivants :

var proxyObj = new Proxy(obj, {

    get: function(tagert,key,receiver){},
    set: function(tagert,key,receiver){},
    has: function(tagert,key){},
    deleteProperty: function(tagert,key){},
    ownKeys: function(tagert){},
    getOwnPropertyDescriptor: function(tagert,key){},
    defineProperty: function(tagert,key,desc){},
    preventExtensions: function(tagert){},
    getPrototypeOf: function(tagert){},
    isExtensible: function(tagert){},
    setPrototypeof: function(tagert,proto){},
    apply: function(tagert,obj,args){},
    construct: function(tagert,args){},
    
})

application proxy get()

Autoriser les indices de tableau à avoir des valeurs négatives

En js, la table inférieure valide des tableaux commence à 0.

var arr = [1,2,3];
console.info(arr[0])  // 1
console.info(arr[-1]) // undefined
console.info(arr[100]) // undefined

Il est à noter que lorsque le tableau suivant est hors limites ou a une valeur négative, le résultat sera indéfini au lieu d'une erreur.

Ci-dessous, nous espérons que le tableau pourra prendre des valeurs négatives comme indiqué dans le tableau ci-dessous. Les règles sont les suivantes :

  • -n signifie le nième élément de. le dernier. Par exemple : -1 signifie le premier élément du dernier.

Utilisez Proxy pour résoudre le problème comme suit :

var arr = [1,2,3];

var proxyArr = new Proxy(arr,{
    get: (target,prop)=>{
        let index = Number(prop);
        if(index < 0){
            prop = target.length + index;
        }
        return target[prop];
        
    }
})
console.info(arr[-1]);      // undefined
console.info(proxyArr[-1]); // 3

Remarque :

  • Number() peut convertir le valeur entrante en type numérique. Valeur non numérique --> NaN;

  • S'il s'agit de proxyArr.push(3), puisque l'accessoire à ce moment est 'push', il n'entrera pas dans la branche if .

  • Si c'est proxyArr[-1], le prop à ce moment est '-1', donc il entrera dans la branche if : changez le prop de -1 à 2, donc atteindre l'effet d'agence.

  • À ce stade, proxyArr peut être utilisé comme un tableau et des méthodes telles que le tri et le push peuvent être appelées. Array.isArray(proxyArr) === true

  • Bien sûr, vous pouvez également l'encapsuler davantage dans une fonction d'usine.

    function myArr(...args){
        var arr = new Array(...args);
    
        var proxyArr = new Proxy(arr,{
            get: (target,key)=>{
                let index = Number(key);
                if(index < 0){
                    key = target.length + index;
                }
                return target[key];
    
            }
        })
        return proxyArr;
    }
    var obj = myArr([1,2,3]);
    console.info(obj[0],obj[-1])

    Fonctionnement en chaîne

    var double = n => n*2;
    var pow2 = n => n*n;
    var half = n => n/ 2;
    var add1 = n => n+1;
    
    function pipe (num){
        let funs = []
        let obj = new Proxy({},{
            get:function(target,prop){
                if(prop === 'end'){
                    return funs.reduce((val,currentfn)=>currentfn(val),num);
                }else{
                    funs.push(window[prop])
                }
                return obj;
            }
        })
    
        return obj;
    };
    
    console.info( pipe(4).double.pow2.end);
    console.info( pipe(4).pow.double.pow2.add1.end);

    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!

Déclaration:
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