ホームページ > ウェブフロントエンド > jsチュートリアル > JS Proxyのメリットと利用シーン

JS Proxyのメリットと利用シーン

Guanhui
リリース: 2020-06-15 09:22:41
転載
4555 人が閲覧しました

JS Proxyのメリットと利用シーン

車を運転する人は車の構造を理解していないことが多いですが、車の構造を深く理解することでさらに大きな効果が得られる可能性があります。

序文

vue3.x のニュースが増えるにつれて、proxy についての議論も増えています。 Object.defineProperty と比較した場合、proxy の違い、利点、用途は何ですか?この記事では、

Object.defineProperty

について簡単に紹介します。

proxy について説明する前に、 Object.defineProperty を確認しましょう。ご存知のとおり、vue2.x とそれ以前のバージョンでは、Object.defineProperty を使用してデータの双方向バインドを実現しています。単純に実装しましょう

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)
ログイン後にコピー
ブラウザで実行してください

コンソール、正常に動作するように見えます

JS Proxyのメリットと利用シーン

しかし実際には

Object.defineProperty 問題は次のとおりです。

問題 1. オブジェクト プロパティの削除または追加を監視できません

たとえば、属性

gender を追加すると、実行中、observer(obj) にはこの属性がないため、監視できません。

を追加すると削除された属性は監視できません。

vue$set を使用して操作する必要があります。$set Object.defineProperty は内部的に操作にも使用されます

JS Proxyのメリットと利用シーン##問題 2. 配列の変更を監視できません

##上の図からわかるように、実際には配列属性は正常に変更されていますが、監視することはできませんJS Proxyのメリットと利用シーン

質問 3。 オブジェクトは再帰的に走査されるため、

Object.defineProperty

を使用してオブジェクトのプロパティがハイジャックされます。走査されるオブジェクト レベルが比較的深い場合は、時間がかかり、パフォーマンスの問題が発生する可能性もあります

proxy

proxy

の場合、mdn の説明は次のとおりです: オブジェクトは、基本的な操作 (属性の検索、割り当て、列挙など) のカスタム動作を定義するために使用されます。 、関数呼び出しなど)

簡単に言うと、ターゲット オブジェクトにインターセプトのレイヤーを設定できます。ターゲット オブジェクトに対してどのような操作が実行される場合でも、このインターセプト層を通過する必要があります。

proxy

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)
ログイン後にコピー
同じ効果

##そして、

Object.definePropertyJS Proxyのメリットと利用シーン Things属性

gender

の追加などの実行できない操作は、

操作配列を監視でき、また

JS Proxyのメリットと利用シーン も監視できます。

最後に、黒板をノックして、2 つの違いを簡単にまとめます。

JS Proxyのメリットと利用シーン1.

Object.defineProperty

インターセプトされるのはオブジェクトのプロパティです。これにより、元のオブジェクトが変更されます。

proxy

はオブジェクト全体をインターセプトし、元のオブジェクトを変更せずに new を通じて新しいオブジェクトを生成します。 2.proxy 上記の get および set に加えて、他にも 11 個のインターセプト メソッドがあります。プロキシを選択するにはさまざまな方法があり、配列の監視、オブジェクト プロパティの追加と削除の監視など、

Object.defineProperty

ではできない一部の操作を監視することもできます。 プロキシの使用シナリオ

プロキシの使用シナリオについては、スペースの制限のため、ここでは単にいくつかを列挙しますが、さらに多くのシナリオを列挙することができます。私の github ノートまたは mdn に従ってください。

これを見ると、この 2 つの違いと proxy の利点がすでにわかりました。しかし、開発では、

proxy

はどのようなシナリオで使用できますか? 発生する可能性のあるいくつかの状況を次に示します 負のインデックス配列

## を使用する場合#splice(-1)slice(-1)

およびその他の API では、負の数値を入力すると、配列の最後の項目が配置されますが、通常の配列上にあり、負の数になります。数字は使用できません。

[1,2,3][-1] このコードでは 3 を出力できません。上記のコードを出力 3 にするには、proxy を使用することもできます。 rreeee<h3 class="heading" data-id="heading-5"><span style="font-size: 16px;">表单校验</span></h3> <p>在对表单的值进行改动的时候,可以在 <code>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;
ログイン後にコピー

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)
ログイン後にコピー

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)
ログイン後にコピー

JS Proxyのメリットと利用シーン

推荐教程:《JS教程》    

以上がJS Proxyのメリットと利用シーンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.im
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート