2017-03-22 7 views
1

プロキシを使用していないプロパティにアクセスするときにtypeErrorの代わりにundefinedを返す小さなラッパーを作成しました。コードは次のとおりです。es6プロキシセーフな深いオブジェクト

function proxify(event) { 
    var proxy = new Proxy(event, { 
     get: function (target, property) { 
      if (property in target) { 
       return target[property]; 
      } else { 
        return ''; 
      } 
      } 
     } 
    }); 
    return proxy; 
} 

これは、プロパティが1レベル深くない場合に機能します。例えば 、obj.somethingが存在しないと仮定すると:オブジェクトのプロパティが深くネストされた

obj.something.else.deeper 

ある場合

obj.something.else 

は、私は例外TypeError

私を受け取る未定義

を返す。しかします問題は、深いネストされたオブジェクトを処理するために上記の関数をどのように拡張するのですか?あなたのproxify関数内で戻り値をラップする必要が

Thxを

+0

'obj.something'は、文字列ではなく、別のプロキシを返すようにする必要があります。 – Bergi

+0

@Bergiどのくらいの深さの物件があるかを判断する方法はないようです。親が存在しないことが分かっていれば、私は別のプロキシを呼び出すことができました。もし私が何かを見逃していれば、一例が大好きです。 thx – Cyph

+0

これは決まったものではありません。それは単に動的なプロパティアクセスです。常にプロキシを返す必要があります。 – Bergi

答えて

2

:正直なところで

function proxify(event) { 
    return isPrimitive(event) ? event : new Proxy(event, { get: getProp }); 
} 
function isPrimitive(v) { 
    return v == null || (typeof v !== 'function' && typeof v !== 'object'); 
} 
function getProp (target, property) { 
    if (property in target) { 
    return proxify(target[property]); 
    } else { 
    return proxify({}); 
    } 
} 

、おそらくlodash's _.get()ramda's R.path()のようなものを使用した方がいいでしょう。最初のgetProp()から深い評価が何層になるかを知る方法はないので、次のプロパティへのアクセスが傍受されるように、プリミティブな値または "真実な" Proxyインスタンスを常に返す必要があります)。一方、_.get()メソッドは文字列を受け取り、最初の呼び出しからすぐに多くのレベルにアクセスしようとしていることをすぐに知ることができます。

+0

私は正しくフォローしています。 funcを使用した例を表示できますか?私は上記で共有しました。 – Cyph

+0

@Cyph編集を参照してください。 – idbehold

+0

私は少しのテストをしました、私は同意します。 lodash _.getは今のところ行く方法のようです。私はシンプルなドットアクセサの構文を保持しようとしていたが、サイコロ – Cyph

2

このように、プリミティブ値または新しいプロキシを返す必要があります。 私はあなたがそれを行うためにloDashを必要としないと思うし、はい、ネストされたプロキシの深さを管理することができます! 。( 私の最後のポイント、deepProxyを参照してください。しかし、私はあなたが何をしたいのかわからないから、私はそれらのいくつかの点にご注意を集中たいと思います:

最初の使用(シミュレートチェーン):


function proxify(event){ 
    return isPrimitive(event) ? event : new Proxy(event,{ get: getProp }); 
} 

function isPrimitive(v){ 
    return v == null || (typeof v !== 'function' && typeof v !== 'object'); 
} 

function getProp(target, property){ 
    return (property in target) 
     ? proxify(target[property]) 
     : proxify({}); 
} 

このコードそのままでは、ネストされた特性をシミュレート なく(NO割り当て、次いで無保全ため)任意のメンバー依存性を付与しないであろう。

obj.something.else = 99; 
console.log(obj.something.else) // returning a new Proxy() 

IMO、それは意味がなく、非常に特殊な場合に予約されています。 もう一度、それはあなたの目的が何であるかによって異なります。

第2の使用(深い割り当て):新しいオブジェクトを設定しようとした場合、基本的な連鎖可能なプロキシを使用することにより割り当て

から


基本ではない拡張可能な割り当て

function proxify(defprop={}) 
{ 
    return new Proxy(defprop, handler); 
}; 
var handler = 
{ 
    get: function(target, property, receiver) 
    { 
     if(!(property in target)) 
      target[property] = proxify(); 
     return Reflect.get(target, property, receiver); 
    }, 
}; 

obj.something.else = 99; 
console.log(obj.something.else) // returning 99 

拡張(またはネストされたオブジェクト)を削除すると、この新しいプロパティのルートのみがトラップされます。 これ以上のチェーン化はありません。これは適切ではなく、安全ではありません。この割り当てを仮定し しかし、オブジェクトのプロパティは、

obj.something.else.deeper

(悪い方法)、ネストされた深さである場合:

Cyph:

には、以下のケースを覚えて

var deeper = {toto: "titi"}; 
obj.something.else = deeper; 

console.log(obj.something.else.toto) 
// will return "titi" 

obj.something.else.toto.something.else = {tutu: "tata"}; 
// will return a typeError Again 

(良い方法)チェーン能力を伝播するには セッタートラップ内の真のオブジェクトとして値のタイプをチェックし、各ルートプロパティをプロキシする必要があります。残りの部分はゲッタートラップによって自然に変換されます。

var handler = 
{ 
    get: function(target, property, receiver) 
    { 
     if(!(property in target)) 
      target[property] = proxify(); 
     return Reflect.get(target, property, receiver); 
    }, 
    set: function(target, property, value, receiver) 
    { 
     // extend proxify to appended nested object 
     if(({}).toString.call(value) === "[object Object]") 
      value = deepApply(receiver, property, value); 

     return Reflect.set(target, property, value, receiver); 
    }, 
}; 
var deepApply = function(receiver,property, data) 
{ 
    var proxy = proxify(); 
    var props = Object.keys(data); 
    var size = props.length; 

    for(var i = 0; i < size; i++) 
    { 
     property = props[i]; 
     proxy[property] = data[property]; 
    } 
    return proxy; 
}; 

は深さ


私は私の実際のソリューションを読むためにあなたを招待に管理:deepProxy

    オブジェクト構造があるときにレベルがプロト宣言 経由で自動定義することができます
  • 設定された。次に、現在のフロアを簡単に知り、各レベルの条件付き命令を追加できます。
  • プロパティのパスは、彼のアクセサから到達することができます。
関連する問題