2

さて、私がやろうとしていることを説明させてください。それは基本的な問題のように感じますが、解決するのは非常に難しいようです: 通常の JavaScript オブジェクトがあるとします:

var x = {};

ここで、新しいプロパティ (ここでは使用newPropします) を objectに追加すると、その新しいプロパティとその値を、格納時に親オブジェクトの関数を介して自動的にx渡したいと思います。initializerx

x.initializer = function(propKey, propValue){
  console.log(propKey, 'IS', propValue);
}

x.newProp = 13;

したがって、この場合、x.initializer(x.newProp);定義するときに自動的にトリガーしたいと思いますx.newProp(ボーナスとして、その値を割り当て/変更するたびに)x

セッター/ゲッター、およびプロトタイプを使用してこれを試みましたが、これらのメソッドの複雑さは明らかではなく、制限されているようです。

たとえば、次のようなことをしても:

function setterFunc(value){
  x.initializer("newProp", value); //the name of the property isn't even dynamic.
}
function getterFunc(value){
  return someValue; //SOMEHOW!
}
Object.defineProperty(x, 'newProp', { get: getterFunc,
                                      set: setterFunc,
                                      configurable: true,
                                      enumerable: true });

このアプローチには多くの問題/複雑さがあります。

  1. get/set を使用する性質上、newProp の値は別のキーに格納する必要があります。
  2. 新しいプロパティの名前は隠されています。初期化関数に渡すことができるのは値だけです (私の知る限り)。
  3. ゲッター関数を使用しても、元の保存された値を取得するのは複雑で、何らかのインデックスなどが必要です。
  4. x のプロトタイプを介してすべての新しいプロパティに対して一般的にこれを実装すると、どうやらクレイジーに思えます...ええ?それが可能かどうかさえわかりません。

どんな助けでも大歓迎です...私は途方に暮れています!必要に応じて明確にします。


アップデート

いくつかの提案がありましたが、完全な回答が得られなかったようです。数か月後、いくつかの発見がありましたが、以下にいくつかの候補を示します (完全に最適な候補はありませんが)。

プロキシー

http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies

Rob W によって提案されたものは、目的の機能にほぼ一致しているようです。前述のように、これはどこでも実装されているわけではなく、まだハーモニー ドラフトの一部です。


Object.observe();

http://wiki.ecmascript.org/doku.php?id=harmony:observe

また、ハーモニー仕様の一部である Observe は、(理論上) パフォーマンスへの影響を最小限に抑えてオブジェクトの変更をリッスンします。また、途中です。


Watch.js

https://github.com/melanke/Watch.JS

このクロスブラウザー ライブラリはオブジェクトのプロパティを監視しますが、オブジェクト自体は監視していないようです。したがって、監視するオブジェクトを別のオブジェクトのプロパティに割り当てる必要があるようです。

4

1 に答える 1

3

問題 2 は、プロパティごとに異なるゲッター関数とセッター関数を生成することで解決できます。

function setterFunc(prop) {
  return function(value) {
    x._private[prop] = value;
    x.initializer(prop, value);
  }
}

function getterFunc(prop) {
  return function() {
    return x._private[prop];
  }
}

Object.defineProperty(x, 'newProp', { get: getterFunc('newProp'),
                                      set: setterFunc('newProp'),
                                      configurable: true,
                                      enumerable: true });
于 2013-08-05T20:59:36.617 に答える