Maison > interface Web > js tutoriel > Avantages et scénarios d'utilisation de JS Proxy

Avantages et scénarios d'utilisation de JS Proxy

Guanhui
Libérer: 2020-06-15 09:22:41
avant
4597 Les gens l'ont consulté

Avantages et scénarios d'utilisation de JS Proxy

Les gens qui conduisent des voitures ne comprennent souvent pas la structure de la voiture, mais une compréhension approfondie de la structure de la voiture peut être encore plus puissante

Avant-propos

À mesure que les nouvelles de vue3.x augmentent, les discussions sur proxy augmentent également. Par rapport à Object.defineProperty, quelles sont les différences, les avantages et les applications de proxy ? Cet article présente brièvement

Object.defineProperty

Avant de parler de proxy, passons en revue Object.defineProperty d'abord. Comme nous le savons tous, vue2.x et les versions précédentes utilisent Object.defineProperty pour réaliser une liaison bidirectionnelle de données. Quant à savoir comment les lier ? Implémentons simplement

function observer(obj) {
    if (typeof obj === 'object') {
        for (let key in obj) {
            defineReactive(obj, key, obj[key])
        }
    }
}
function defineReactive(obj, key, value) { //针对value是对象,递归检测
    observer(value) //劫持对象的key
    Object.defineProperty(obj, key, {
        get() {
            console.log('获取:' + key) return value
        },
        set(val) { //针对所设置的val是对象
            observer(val) console.log(key + "-数据改变了") value = val
        }
    })
}
let obj = {
    name: '守候',
    flag: {
        book: {
            name: 'js',
            page: 325
        },
        interest: ['火锅', '旅游'],
    }
}

observer(obj)
Copier après la connexion

et exécutons-le dans console du navigateur. Il semble fonctionner normalement

Avantages et scénarios d'utilisation de JS Proxy

Mais en fait, Object.defineProperty a le. problèmes suivants Plusieurs

questions 1. La suppression ou l'ajout d'attributs d'objet ne peut pas être surveillé

Par exemple, l'ajout d'un attribut gender, car il n'y a pas un tel attribut lors de l'exécution de observer(obj), donc ceci ne peut pas être surveillé arriver. Les attributs supprimés ne peuvent pas être surveillés. Lorsque

ajoute des attributs, vue doit utiliser $set pour fonctionner, et $set utilise également Object.defineProperty pour fonctionner en interne

Avantages et scénarios d'utilisation de JS Proxy

Problème 2. Les modifications dans le tableau ne peuvent pas être surveillées

Avantages et scénarios d'utilisation de JS Proxy

Comme le montre l'image ci-dessus, bien que les attributs du tableau soient effectivement modifié avec succès Mais il ne peut pas être surveillé

Question 3. Puisque l'objet est parcouru de manière récursive, Object.defineProperty est utilisé pour détourner les propriétés de l'objet. Si le niveau de l'objet traversé est profond, cela prendra beaucoup de temps et il peut même y avoir des problèmes de performances

proxy

Pour

, la description sur mdn est : L'objet est utilisé pour définir des comportements personnalisés pour les opérations de base (telles que la recherche d'attributs, l'affectation, l'énumération, l'appel de fonction, etc.) proxy

Pour faire simple, c'est le cas, vous pouvez mettre en place une couche d'interception sur l'objet cible. Quelle que soit l'opération effectuée sur l'objet cible, il doit passer par cette couche d'interception

On dirait que

est plus facile à utiliser que proxy et est beaucoup plus simple, et c'est en fait le cas . Utilisons un proxy pour réécrire le code ci-dessus et essayons Object.defineProperty

function observerProxy(obj) {
    let handler = {
        get(target, key, receiver) {
            console.log('获取:' + key) // 如果是对象,就递归添加 proxy 拦截
            if (typeof target[key] === 'object' && target[key] !== null) {
                return new Proxy(target[key], handler)
            }
            return Reflect.get(target, key, receiver)
        },
        set(target, key, value, receiver) {
            console.log(key + "-数据改变了") return Reflect.set(target, key, value, receiver)
        }
    }
    return new Proxy(obj, handler)
}
let obj = {
    name: '守候',
    flag: {
        book: {
            name: 'js',
            page: 325
        },
        interest: ['火锅', '旅游'],
    }
}
let objTest = observerProxy(obj)
Copier après la connexion
pour obtenir le même effet

Avantages et scénarios d'utilisation de JS Proxy

De plus, il peut faire des choses que

ne peut pas do , par exemple, l'ajout d'un attribut Object.defineProperty peut surveiller le tableau d'opérations gender

Avantages et scénarios d'utilisation de JS Proxy

, et peut également surveiller le

Avantages et scénarios d'utilisation de JS Proxy

Dernier coup au tableau et résumez brièvement les différences entre les deux

1

Ce qui est intercepté est l'attribut de l'objet, qui changera l'objet d'origine. Object.defineProperty intercepte l'objet entier et génère un nouvel objet via new sans changer l'objet d'origine. proxy

2. En plus des get et set ci-dessus, il existe 11 méthodes d'interception pour

. Il existe de nombreuses façons de choisir. Le proxy peut également surveiller certaines opérations qui ne peuvent pas être surveillées par proxy, telles que la surveillance des tableaux, la surveillance de l'ajout et de la suppression d'attributs d'objet, etc. Object.defineProperty

scénarios d'utilisation du proxy

Concernant les scénarios d'utilisation de

, en raison des limitations d'espace, en voici quelques-uns. Vous pouvez en trouver davantage sur mes notes github ou. mdn. proxy

En voyant cela, vous avez déjà une idée approximative de la différence entre les deux et des avantages de

. Mais en développement, quels sont les scénarios dans lesquels proxy peut être utilisé ? Voici quelques situations que vous pouvez rencontrer : proxy

Tableau d'index négatif

lors de l'utilisation de

, splice(-1) Lors de l'utilisation de l'API, lorsqu'un nombre négatif est saisi, le dernier élément du tableau sera positionné. Cependant, les nombres négatifs ne peuvent pas être utilisés sur des tableaux ordinaires. slice(-1) Ce code n'affiche pas 3 . Pour que le code ci-dessus génère 3, vous pouvez également utiliser [1,2,3][-1] pour y parvenir. proxy

<br>
Copier après la connexion

Avantages et scénarios d'utilisation de JS Proxy

表单校验

在对表单的值进行改动的时候,可以在 set 里面进行拦截,判断值是否合法

let ecValidate = {
    set(target, key, value, receiver) {
        if (key === &#39;age&#39;) { //如果值小于0,或者不是正整数
            if (value < 0 || !Number.isInteger(value)) {
                throw new TypeError(&#39;请输入正确的年龄&#39;);
            }
        }
        return Reflect.set(target, key, value, receiver)
    }
}
let obj = new Proxy({
    age: 18
},
ecValidate) obj.age = 16obj.age = &#39;少年&#39;
Copier après la connexion

Avantages et scénarios d'utilisation de JS Proxy

增加附加属性

比如有一个需求,保证用户输入正确身份证号码之后,把出生年月,籍贯,性别都添加进用户信息里面

众所周知,身份证号码第一和第二位代表所在省(自治区,直辖市,特别行政区),第三和第四位代表所在市(地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码)。第七至第十四位是出生年月日。低17位代表性别,男单女双。

const PROVINCE_NUMBER = {
    44 : &#39;广东省&#39;,
    46 : &#39;海南省&#39;
}
const CITY_NUMBER = {
    4401 : &#39;广州市&#39;,
    4601 : &#39;海口市&#39;
}
let ecCardNumber = {
    set(target, key, value, receiver) {
        if (key === &#39;cardNumber&#39;) {
            Reflect.set(target, &#39;hometown&#39;, PROVINCE_NUMBER[value.substr(0, 2)] + CITY_NUMBER[value.substr(0, 4)], receiver) Reflect.set(target, &#39;date&#39;, value.substr(6, 8), receiver) Reflect.set(target, &#39;gender&#39;, value.substr( - 2, 1) % 2 === 1 ? &#39;男&#39;: &#39;女&#39;, receiver)
        }
        return Reflect.set(target, key, value, receiver)
    }
}
let obj = new Proxy({
    cardNumber: &#39;&#39;
},
ecCardNumber)
Copier après la connexion

Avantages et scénarios d'utilisation de JS Proxy

数据格式化

比如有一个需求,需要传时间戳给到后端,但是前端拿到的是一个时间字符串,这个也可以用 proxy 进行拦截,当得到时间字符串之后,可以自动加上时间戳。

let ecArrayProxy = {
    get(target, key, receiver) {
        let _index = key < 0 ? target.length + Number(key) : key
        return Reflect.get(target, _index, receiver)
    }
}
let arr = new Proxy([1, 2, 3], ecArrayProxy)
Copier après la connexion

Avantages et scénarios d'utilisation de JS Proxy<br>

推荐教程:《JS教程》    <br>

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:juejin.im
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