ES 6入門のProxy

4467 ワード

1.概要
Proxyは、いくつかの操作のデフォルトの動作を修正するために使用され、言語レベルでの修正に相当するので、プログラム言語をプログラミングする『元プログラミング』に属します.
1.1理解
Proxyは、ターゲットの前に「ブロック」を構築し、外部からの訪問は、その層を通過する必要があります.そのためブロックの中で外部からのアクセスをフィルタリングして書き換えます.
Es 6では、元のProxy構成関数を提供し、Proxyのインスタンスを生成するために使用することができる.
let proxy = new Proxy(target, handler)
Proxyオブジェクトの使い方はすべて上の形式で、違いはハンドルパラメータの書き方だけです.ここでnew Proxy()はProxyを生成する例を示し、targetパラメータは全てのブロッキングの対象を表し、handlerパラメータも対象であり、ブロッキング挙動をカスタマイズするために用いられる.以下のとおりです
let proxy = new Proxy({}, {
    get: function(target, property) {
        return 35
    }
})

proxy.time // 35
proxy.name // 35
proxy.title // 35
解読:
上記では、構造関数として、Proxyは2つのパラメータを受け入れます.最初のパラメータは代理の対象となりますが、Proxyの介入がなければ、操作はもともとこの対象です.第二のパラメータは、各プロキシオブジェクトの動作に対して具体的な関数とブロッキング動作を提供する構成オブジェクトである.上記のコードには、ターゲットの属性に対するアクセス要求をブロックするためのget関数があります.
また、Proxyを機能させるには、ターゲットオブジェクトに対してではなくProxyのインスタンスを操作しなければならない.
もしハンドルにブロックが設定されていないなら、元のオブジェクトに直接に通じるのと同じです.以下のとおりです
let target = {}
let handler = {}
let proxy = new Proxy(target, handler)


proxy.a = 'b'
target.a = 'b'
上記の例では、Proxyオブジェクトは、Object.proxy属性に設定されていますので、Objectオブジェクトで呼び出すことができます.

let object = {proxy: new Proxy(target, handler)}
Proxy例は、他のオブジェクトの原型オブジェクトとしてもよい.
let proxy = new Proxy({}, {
    get: function(target, property) {
        retrun 35
    }
})

let obj = Object.create(proxy)
obj.time    // 35

        ,          。
一般的なProxyサポートのブロック操作は以下の通りです.
  • get(targt、propKey、receiver):対象属性の読み取りをブロックします.例えば、proxy.fooとproxy[foo]
  • set:対象属性の設定をブロックします.例えば、proxy.foo=vまたはproxy[foo]=v、ブール値
  • を返します.
  • has(target、proKey):propKey in proxyをブロックする操作は、ブール値
  • を返します.
  • apply:Proxy例を関数として呼び出す操作、例えばproxy(…args)、proxy.call(object,…args)、proxy.appy(…).
  • deleteProperty:delete proxyをブロックする動作は、ブール値
  • を返します.
  • ownKeys:Object.getOwnProPertyNamesをブロックして、1つの配列を返します.この方法は対象オブジェクトの属性名をすべて返し、Object.keys()の戻りは対象オブジェクト自身のエルゴード属性のみを含む.
  • 1.2 get()
    get方法は、ある属性の読み取り動作をブロックするために使用され、ターゲットオブジェクト、属性名、およびproxyインスタンス自体の順に3つのパラメータを受け入れることができ、最後のパラメータは任意である.
    let p = {
        name: '  '
    }
    
    let proxy = new Proxy(p, {
        get: function(target, property) {
            if (property in target) {
                retrun target[property]
            } else {
                console.log('  ')
            }
        }
    })
    
    proxy.name // '  '
    proxy.age  // '  '
    
    注意点
  • get方法は、
  • を継承することができる.
  • get方法は、チェーン操作
  • を行うことができる.
    1.3セット
    set方法は、ある属性の割当動作をブロックするために使用され、4つのパラメータを適用して、対象オブジェクト、属性名、属性値、およびProxyインスタンス自体として順次適用し、最後のオプションを選択します.
    let v = {
        set: function(obj, prop, value) {
             if (prop === 'age') {
                 if(!Number.isInteger(value)) {
                     console.log('  ')
                 }
                 
                 if(value > 200) {
                     console.log('  ')
                 }
                 
                 obj[prop] = value
             }
        }
    }
    
    let p = new Proxy({}, v)
    
    p.age = 100
    
    p.age   // 100
    
    p.age = 'n'
    p.age   //   
    
    set法を利用して、データバインディングができます.つまり、オブジェクトが変化するたびに、自動的にDomを更新します.
    ターゲット自身の属性が書き込み不可で設定不可能である場合、セット方法は機能しません.
    1.4 appy()
    applyメソッドブロック関数の呼び出し、call、apply操作.ターゲットオブジェクト、オブジェクトのコンテキストオブジェクト、ターゲットオブジェクトのパラメータ配列は、3つのパラメータを受け入れることができます.
    let h = {
        apply(target, ctx, args) {
            return Reflect.apply(...arguments)
        }
    }
    
    let target = function() {return 'haha')
    let h = {
        apply: function() {
            return 'heihei'
        }
    }
    
    let p = new Proxy(taraget, h)
    
    p() // 'heihei'
    
    
    1.5 has
    hasメソッドは、Has Property操作をブロックするために用いられます.つまり、オブジェクトがある属性を持つかどうかを判断するときに、この方法が有効になります.
    has方法は、2つのパラメータを受け入れることができます.それぞれのターゲット、クエリーが必要な属性名です.
    注意:hasメソッドでブロックする場合は、HasOwnProperty操作ではなく、Hasメソッドは、属性がオブジェクト自身の属性か、それとも継承の属性かを判断しません.
    1.6 construct
    constructメソッドはnewコマンドをブロックするために使用されます.以下はブロック対象の書き方です.
    let h = {
        construct(target, args, newTarget) {
            retrun new target(...args)
        }
    }
    
    target:     
    args:          
    newTarget:        ,new         
    
    1.7 deleteProperty()
    deleteProperty方法はdelete操作をブロックするために使用されます.この方法がエラーを投げたりfalseに戻ったりすれば、現在の属性はdeleteコマンドによって削除されません.
    2.this問題
    Proxyは、ターゲットオブジェクトへのアクセスを代行することができますが、ターゲットオブジェクトの透明エージェントではなく、ブロックを一切しない場合も、ターゲットオブジェクトの動作が一致することは保証されません.主な原因はProxyエージェントの場合、ターゲットオブジェクト内部のthisキーワードがProxyエージェントに向けられているからです.
    公衆番号に注目【小若死にさん】