Javascript プロキシと Reflect API について

Mary-Kate Olsen
リリース: 2024-10-07 16:24:29
オリジナル
841 人が閲覧しました

Understanding Javascript

導入

JavaScript では、プロキシを使用すると、特定のオブジェクトの操作をトラップし、カスタマイズできます。プロキシは、オブジェクトと「現実世界」の間の仲介者として機能します。したがって、オブジェクトの基本操作を強化して、より複雑なロジックを実装したり、ニーズに合わせて基本操作を再定義したりできます。

ユースケースには以下が含まれます:

  • プロパティへのアクセスをログに記録します。デバッグに役立ちます
  • オブジェクトとの対話を検証します (フォーム検証など)
  • に一貫した書式設定を適用するのに役立ちます

プロキシは 2 つのパラメータを取ります:

  • ターゲット: プロキシする元のオブジェクトです
  • ハンドラー: インターセプトする操作と、その操作を再定義する方法を定義するオブジェクト

基本的な例


const target = {
    greeting1: "Hello",
    greeting2: "Good morning"
}

const handler = {
    get(target, prop, receiver) {
        return target[prop] + " friends!"
    }
}

const proxy = new Proxy(target, handler)

console.log(proxy.greeting1) // Hello friends!
console.log(proxy.greeting2) // Good morning friends!



ログイン後にコピー

この例では、プロキシを定義します。ターゲット オブジェクトには 2 つのプロパティがあります。 get() ハンドラーの実装を提供するハンドラーを定義します。 get トラップはターゲット オブジェクトのプロパティへのアクセスをインターセプトし、その中で必要に応じて動作を変更できます。

この設定では、ターゲット オブジェクトのプロパティにアクセスするたびに、ハンドラーがそれをインターセプトし、実装したコードを実行することを意味します。私たちの場合は、プロパティ値を取得して友達を追加するだけです!

反映する

多くの場合、プロキシは Reflect API とともに使用されます。 Reflect は、プロキシ トラップと同じ名前のメソッドを提供します。その名前が示すように、これは、対応するオブジェクトの内部メソッドを呼び出すためのセマンティクスを反映します。


const target = {
    greeting1: "Hello",
    greeting2: "Good morning"
}

const handler = {
    get(target, prop, receiver) {
        return Reflect.get(...arguments) + " friends!"
    }
}

const proxy = new Proxy(target, handler)

console.log(proxy.greeting1) // Hello friends!
console.log(proxy.greeting2) // Good morning friends!


ログイン後にコピー

Reflect はプロキシを使用する必要はありませんが、Reflect を使用すると、動作がネイティブの Javascript エンジンの操作と一致していることを確認できます。また、将来の更新との互換性が確保され、意図しない副作用が防止され、コードが簡素化されます。これがなければ、開発者はプロパティへのアクセス、割り当て、削除などの動作を再実装する必要があります。これはエラーが発生しやすく、JavaScript のネイティブ動作と矛盾する可能性があります。

プロキシで何ができるかを調べるためにいくつかの例を構築してみましょう。

ロギング

最初の例では、オブジェクトに対してどのようなアクションが行われたかをログに記録したいとします。プロパティを取得、設定、削除するたびに、コンソールに出力したいと考えています。これはデバッグ目的に役立つ可能性があります。


const target = {
    name: "Damien",
    age: 32,
    status: "WRITING"
}

const loggerHandler = {
    get(target, prop, receiver) {
        if (prop in target) {
            console.log(`[LOG] Accessing property ${prop}. Current value is ${target[prop]}`)
            return Reflect.get(...arguments)
        } else {
            console.error(`[LOG] Error accessing non-existent property ${prop}`)
        }

    },

    set(target, key, value) {
        console.log(`[LOG] Setting property ${key}. New value: ${value}`)
        return Reflect.set(...arguments)
    },

    deleteProperty(target, prop) {
        console.warn(`[LOG] Deleting property: ${prop}`)
        return Reflect.deleteProperty(...arguments)
    }
}

const proxy = new Proxy(target, loggerHandler)

proxy.name // [LOG] Accessing property name. Current value is Damien
proxy.status // [LOG] Accessing property status. Current value is WRITING

proxy.name = "Bob" // [LOG] Setting property name. New value: Bob
proxy.status = "NAPPING" // [LOG] Setting property status. New value: NAPPING

proxy.job = "Developer" // [LOG] Setting property job. New value: Developer

delete proxy.job // [LOG] Deleting property: job

proxy.job // [LOG] Error accessing non-existent property job


ログイン後にコピー

取得、設定、削除という 3 つの基本操作を再定義する loggerHandler を定義しました。アクションごとに、何が起こっているかを説明する内容をコンソールに記録します。プロキシの利点は、毎回コンソール ステートメントを記述する必要がないことです。いつものようにオブジェクトと対話し、プロキシがログ動作を処理します。かなりクールですね?

入力検証

2 番目の例では、プロキシを使用してフォーム データの入力検証を実行します。


const validationRules = {
    name: value => value.length >= 3 || "Name must be at least 3 characters long",
    age: value => Number.isInteger(value) || "Age must be a number",
    email: value => value.includes('@') || "Enter a valid email"
}

let formData = {
    name: "",
    age: null,
    email: ""
}

const formHandler = {
    set(target, key, value) {
        if (typeof value === "string") {
            value = value.trim()
        }
        const validationResult = validationRules[key](value)
        if (validationResult !== true) {
            console.error(`Validation failed for property ${key}: ${validationResult}`)
            return false;
        }

        return Reflect.set(...arguments)
    }
}

const formProxy = new Proxy(formData, formHandler)

formProxy.age = "32 years old" // Validation failed for property age: Age must be a number
formProxy.name = "Da" // Validation failed for property name: Name must be at least 3 characters long
formProxy.email = "damcoss mail.com" // Validation failed for property email: Enter a valid email

formProxy.age = 32 // OK
formProxy.name = "Damien" // OK
formProxy.email = "damcoss@mail.com" // OK


ログイン後にコピー

ここでは、値が有効かどうかを検証するために使用されるさまざまなメソッドを備えたオブジェクトを定義します。次に、同じロジックを使用します。プロキシしたいターゲットオブジェクトの formData があります。 formHandler で、set() メソッドを再定義して、入力値に検証ルールを適用します。

結論

プロキシは、Reflect API と組み合わせることで、オブジェクトの操作を傍受してカスタマイズするための柔軟で強力なツールです。これらを使用すると、動作を動的に強化および制御できます。 Reflect API を使用すると、動作が Javascript エンジンと一貫していることも確認できます。

プロキシは、リアクティブ プログラミング、API ラッパー、プロパティ監視などの高度な動作を可能にするために、ライブラリやフレームワークでよく使用されます。

楽しんでください❤️

以上がJavascript プロキシと Reflect API についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!