5

ES6 Proxies について読んでいたとき、この例を見るまでは理解するのに十分簡単に​​思えました。

私は困惑しています。私は彼らが使用する「ウェット/ドライ」という用語を理解していません。また、特に見つけられないように見えるため、いつこれが理想的な選択になるのかわかりません.

これがどのようなシナリオで発生するかについて、誰かが簡単に説明できますか?

4

1 に答える 1

7

まず、少し基本的なことを説明します。オブジェクトはプロパティのコレクションです (その一部は関数であり、正式には「メソッド」と呼ばれています)。これは当たり前のように聞こえるかもしれませんが、重要です。オブジェクトとプロパティ名で他の値を参照します。

プロキシを使用すると、(含む) オブジェクトとプロパティ名のタプルによって、他の値を参照するための規則を書き直すことができます。たとえば、「プライベート」メンバーをプロキシの背後に隠すことができます。

しかし、循環オブジェクト参照があるとします。例えば、

var x = { z: function() { throw new Error("This shouldn't be callable"); };
var X = /* proxy representing x, where X.z is hidden and cannot be called */;

var y = { x: x };
x.y = y;

または、ドキュメント オブジェクト モデルの用語では、document.documentElement.ownerDocument == ドキュメントです。

通常のプロキシでは、Xy を参照すると y が返されます。Xyx === x と Xyx !== X を除いて、実際には何も問題はありません。したがって、次のように呼び出すことができます。

X.y.x.z(); // throws new Error("This shouldn't be callable")

メンブレンは、非プリミティブプロパティ (オブジェクトと関数) がこの同一性関係を保持し、プロパティ ルックアップの任意の組み合わせによって設定されたプロキシ ルールを維持することを保証するものです。メンブレンは、さまざまなオブジェクトの基礎となる (おそらくネイティブの) 実装に誤って直接アクセスすることを防ぎます。

X が x の膜ベースのプロキシである場合、Xy はy を返しません。代わりに、y のプロキシを返します。これを Y と呼びます。X が x のプロパティを公開するのと同じように、Y は y のプロパティを公開します。

さらに重要なことに、Xyx について言及するとします。

X.y.x === X; // true
X.y.x !== x; // also true
typeof X.y.x.z // returns "undefined", not "function"
X.y.x.z(); // throws TypeError("X.y.x.z is not a function")

X への参照 (x のプロキシ) は、メンブレンを介して返されます。したがって、ID プロパティは保持されます。(xyx === x なので、Xyx === X.)

最も重要な概念は次のとおりです。メンブレンとは、元のオブジェクトが表示されず、それらを表すプロキシ オブジェクトのみが表示されることを意味します。

var X = (function() {
    var x = { z: function() { throw new Error("This shouldn't be callable"); };
    var y = { x: x };
    x.y = y;

    var X = /* membrane proxy representing x, where X.z is hidden and cannot be called */;
    return X;
})();

X.y.x === X; // still true

Tom van Cutsem の JavaScript Membranes に関する記事 (あなたが上で引用したものの 1 つ)では、値 x、y、および xz はすべて「ウェット」オブジェクト グラフの一部と見なすことができますが、X または Y を介して参照されるものはすべて、 「ドライ」オブジェクト グラフ。(ここでのグラフという用語は、離散数学の研究の一部であるグラフ理論から来ています。オブジェクトグラフは、関連するオブジェクトのセットを意味し、膜は、「ネイティブ」オブジェクトのセットをそれらのオブジェクトへのプロキシのセットから分離するものです。 )

x と y の値は、関数の外部から直接アクセスできません。(JavaScript の用語では、この例ではローカル変数ですが、メンブレンの観点からは誤解を招く部分もあります。DOM ドキュメントについて話している場合、Mozilla Firefox のような Web ブラウザーで実際に取得しているのは、ネイティブ メモリからの実際のドキュメント オブジェクトではなく、DOM ドキュメントです。それがローカル変数であろうと、実行中の JavaScript のスコープに挿入された値であろうと、メンブレンとそのプロキシは気にしません。)

代わりに、x、y、およびそれらのプロパティへの唯一のアクセスは、X メンブレン プロキシ、および X から取得するすべてのプロパティを介することです。メンブレンであるため、そのアクセスは常に間接的です。

これが発生するシナリオについては、コンピューターのファイル システムへのアクセスなど、あらゆる種類の操作を実行できる信頼できるコードがあるとします。Web ページがファイル システムから直接読み取ったり、最悪の場合、ファイル システムに書き込んだりしたくない場合。プロキシの膜は、公開する予定のプロパティとメソッドのみを公開することで、Web ページが使用できる API を減らし、その信頼できるコードへの偶発的なアクセスの可能性を大幅に減らします。これにより、セキュリティの悪用がはるかにまれになります。

何よりも、メンブレンの実装が正しい場合 (これは思ったよりもはるかに難しいことです)、Web ページの JavaScript はプロキシを扱っていることを認識したり気にしたりしません。 Web ページ スクリプトは、通常の DOM を扱っていると認識しています。それが私たちが望むものです。

于 2016-08-01T06:06:56.313 に答える