开发者

ECMAScript Associative Array via Object w/ prototype null?

I see a lot of people doing this

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" );
  }
}

My question is rather than testing .hasOwnProperty each time you wish to use an Object as a hash why not just set the .__proto__ to null on the object? †

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

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

It has been brought to my attention that __proto__ is nonstandard. That still doesn't answer the question though...

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

This can't be an original question, but I can't find anything about ch开发者_如何学运维anging __proto__ to null to eliminate the drawbacks of having to check for inheritance? What's wrong with this approach, seems to make code faster (don't have to check properties of Object) and cleaner?

† And the .prototype property if you plan on making future children of it.


There's nothing inherently wrong with creating [[Prototype]]'less objects to avoid hasOwnProperty-based checks during "hash" enumeration.

In fact, some of the libraries I know (fuse.js being one of them, IIRC) do exactly that.

Now on to the practical problems:

  1. __proto__ is non-standard. See my compat. table. Notice how IE doesn't support __proto__ up until and including IE9. Of course, IE9 supports Object.create and so it becomes possible to create [[Prototype]]'less object with Object.create(null) but that still leaves IE6, IE7 and IE8. Oh and Opera <10.10, as you can see (which doesn't support Object.create). Fortunately, existence (and functionality) of __proto__ can be easily feature tested, which is why non-supporting browsers can be made to take hasOwnProperty-based or some other route.

  2. Removing [[Prototype]] from the object "removes" all of the Object.prototype.* methods. Naturally. So, for example, myHash.toString() (or even myHash + '') will now error out unless you give that hash toString method. Ditto for valueOf, hasOwnProperty, and all the other Object.prototype.* methods. This isn't big deal, of course, as you can always define those methods (and probably should — to make them specialized for hash usage) but it's more work nevertheless.

As far not finding anything about this approach... I was talking about it at least 2 years ago :) — http://groups.google.com/group/comp.lang.javascript/msg/9451c45080b5e9f0 (likely earlier too, but can't find any other posts on comp.lang.javascript at the moment). There are more interesting findings about browsers' behavior with __proto__ === null in that thread. Check it out.


Not all JS implementations have __proto__ as it is non-standard feature.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜