4

私はこれをやっている人をたくさん見ます

Object.prototype.foo = 'HALLO';
var hash = {baz: 'quuz'};

for ( var v in hash ) {
  // Do not print property `foo`
  if ( hash.hasOwnProperty(v) ) {
    console.log( v + " is a hash property" );
  }
}

私の質問は、をハッシュとして.hasOwnProperty使用するたびにテストするのではなく、なぜオブジェクトにtoを設定しないのですか? †</p> Object.__proto__null

hash.prototype = null;
hash.__proto__ = null;

for ( var v in hash ) {
  // Do not print property `foo`
  console.log( v + " is a hash property" );
}

__proto__非標準であることが私の注意を引きました。それはまだ質問に答えていませんが...

var foo = Object.create(null); Object.getPrototypeOf(foo);

これは元の質問ではありませんが、継承をチェックする必要があるという欠点を排除するために変更することについて何も見つかりませんか? このアプローチの何が問題なのですか。コードを高速化 (のプロパティをチェックする必要はありません) し、よりクリーンにしているようです。__proto__nullObject

† また、.prototype将来その子を作成する予定がある場合は、そのプロパティ。

4

2 に答える 2

4

[[Prototype]] のないオブジェクトを作成して、「ハッシュ」列挙中の に基づくチェックを回避することには、本質的に問題はありません。hasOwnProperty

実際、私が知っているいくつかのライブラリ (fuse.js はその 1 つ、IIRC) はまさにそれを行います。

次に、実際の問題に進みます。

  1. __proto__ は非標準です。私のコンパットを参照してください。テーブル。IE が IE9 まで __proto__ をサポートしていないことに注意してください。もちろん、IE9 が対応Object.createしているので [[Prototype]] レスのオブジェクトを作成することも可能になりますObject.create(null)が、それでも IE6、IE7、IE8 のままです。ご覧のとおり、ああ、Opera <10.10 (これは をサポートしていませんObject.create)。hasOwnProperty幸いなことに、 __proto__ の存在 (および機能) は簡単に機能テストできます。そのため、サポートされていないブラウザーは、ベースまたは他のルートを取ることができます。

  2. オブジェクトから [[Prototype]] を削除すると、すべてのObject.prototype.*メソッドが「削除」されます。当然。したがって、たとえばmyHash.toString()(またはmyHash + '') は、そのハッシュtoStringメソッドを指定しない限りエラーになります。valueOfhasOwnProperty、および他のすべてのObject.prototype.*メソッドについても同様です。もちろん、これは大したことではありません。これらのメソッドはいつでも定義できるため (そして、ハッシュの使用に特化したものにするために、おそらくそうするべきです)、それにもかかわらず、より多くの作業が必要になります。

このアプローチについて何も見つけられない限り...私は少なくとも2年前にそれについて話していました:) — http://groups.google.com/group/comp.lang.javascript/msg/9451c45080b5e9f0 (おそらく以前にも、しかし、現時点では comp.lang.javascript に関する他の投稿は見つかりません)。そのスレッドで __proto__ === null を使用したブラウザーの動作に関する興味深い調査結果があります。見てみな。

于 2011-06-03T15:27:57.890 に答える
0

__proto__非標準機能であるため、すべての JS 実装にあるわけではありません。

于 2011-05-28T03:27:12.910 に答える