Ассоциативный массив ECMAScript через объект с прототипом null? - PullRequest
4 голосов
/ 28 мая 2011

Я вижу, что многие люди делают это

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 каждый раз, когда вы хотите использовать 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__ на null, чтобы устранить недостатки наличияпроверить на наследство?Что плохого в этом подходе, кажется, делает код быстрее (не нужно проверять свойства Object) и чище?

† И свойство .prototype, если вы планируете сделать его будущим потомком.

Ответы [ 2 ]

4 голосов
/ 03 июня 2011

В нет ничего неправильного с созданием [[Prototype]] 'объектов поменьше, чтобы избежать проверок на основе hasOwnProperty при перечислении "хеша".

На самом деле, некоторые из известных мне библиотек (fuse.js является одной из них, IIRC) делают именно это.

Теперь перейдем к практическим задачам:

  1. __proto__ нестандартный . Смотрите мой compat. таблица . Обратите внимание, что IE не поддерживает __proto__ вплоть до IE9 включительно. Конечно, IE9 поддерживает Object.create, и поэтому становится возможным создать [[Prototype]] 'меньше объектов с Object.create(null), но это все еще оставляет IE6, IE7 и IE8. Ох и Opera <10.10, как вы можете видеть (которая не поддерживает <code>Object.create). К счастью, существование (и функциональность) __proto__ может быть легко протестировано, поэтому не поддерживающие браузеры могут работать на hasOwnProperty или другом маршруте.

  2. Удаление [[Prototype]] из объекта «удаляет» все методы Object.prototype.*. Естественно. Так, например, myHash.toString() (или даже myHash + '') теперь будут выдавать ошибку, если вы не дадите этот хеш-метод toString. То же самое для valueOf, hasOwnProperty и всех других Object.prototype.* методов. Конечно, в этом нет ничего сложного, поскольку вы всегда можете определить эти методы (и, вероятно, должно - сделать их специализированными для использования хэшей), но, тем не менее, это более сложная работа.

Пока что ничего не нашел об этом подходе ... Я говорил об этом, по крайней мере, 2 года назад :) - http://groups.google.com/group/comp.lang.javascript/msg/9451c45080b5e9f0 (возможно, и раньше, но не могу найти другие посты на comp.lang .javascript на данный момент). В этой теме есть более интересные выводы о поведении браузеров с __proto__ === null. Проверьте это.

0 голосов
/ 28 мая 2011

Не все реализации JS имеют __proto__, поскольку это нестандартная функция.

...