Мне нужно провести некоторый эксперимент, и мне нужно знать какой-то уникальный идентификатор для объектов в javascript, чтобы я мог видеть, совпадают ли они. Я не хочу использовать операторы равенства, мне нужно что-то вроде функции id () в python.
Есть ли что-то подобное?
javascript
Стефано Борини
источник
источник
Ответы:
Обновление Мой первоначальный ответ ниже был написан 6 лет назад в стиле, соответствующем времени и моему пониманию. В ответ на некоторый разговор в комментариях, более современный подход к этому заключается в следующем:
Если у вас устаревшие требования к браузеру, проверьте здесь совместимость с браузером для
Object.defineProperty
.Исходный ответ приведен ниже (а не просто в истории изменений), потому что я думаю, что сравнение ценное.
Вы можете попробовать следующее. Это также дает вам возможность явно установить идентификатор объекта в его конструкторе или где-либо еще.
Позаботьтесь о том, чтобы любой член, который вы используете для внутреннего хранения уникального идентификатора, не конфликтует с другим автоматически созданным именем члена.
источник
object.hasOwnProperty(member)
при использованииfor..in
цикла. Это хорошо задокументированная практика, и она соблюдается jslintdefineProperty(…, {enumerable:false})
. И самuid
метод вObject
любом случае должен быть в пространстве имен4
как бы вы затем назначили obj с идентификатором 4 переменной, чтобы вы могли что-то с ней делать ... например, обращаться к ее свойствам?Насколько я понимаю, любой ответ, опубликованный здесь, может иметь неожиданные побочные эффекты.
В среде, совместимой с ES2015, вы можете избежать побочных эффектов с помощью WeakMap .
источник
return currentId
?WeakMap
в отличие отMap
? Эта функция выйдет из строя, если вы предоставите ей строку или число.Последние версии браузеров предоставляют более чистый метод расширения Object.prototype. Этот код сделает свойство скрытым от перечисления свойств (для p in o)
Для браузеров, реализующих defineProperty , вы можете реализовать свойство uniqueId следующим образом:
Подробнее см. Https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty.
источник
Собственно, вам не нужно изменять
object
прототип и добавлять туда функцию. Следующее должно хорошо работать для вашей цели.источник
object
хаки. вам нужно запускать его только тогда, когда вы хотите, чтобы объект OP совпал, и он не вмешивается в остальное время.Для браузеров, реализующих этот
Object.defineProperty()
метод, приведенный ниже код генерирует и возвращает функцию, которую можно привязать к любому объекту, которым вы владеете.Преимущество этого подхода в том, что он не расширяется
Object.prototype
.Код работает, проверяя, имеет ли данный объект
__objectID__
свойство, и определяя его как скрытое (неперечисляемое) свойство, доступное только для чтения, если нет.Таким образом, он защищен от любых попыток изменить или переопределить
obj.__objectID__
свойство только для чтения после того, как оно было определено, и последовательно выдает приятную ошибку вместо тихой ошибки.Наконец, в весьма крайнем случае, когда
__objectID__
для данного объекта уже был определен какой-то другой код , это значение просто будет возвращено.источник
Код jQuery использует собственный
data()
метод в качестве идентификатора.В методе за кулисами
data
создается очень специальное поле сobject
именем"jQuery" + now()
put there next id потока уникальных идентификаторов, напримерЯ бы посоветовал вам использовать тот же метод, поскольку Джон Ресиг, очевидно, знает все о JavaScript, и его метод основан на всех этих знаниях.
источник
data
метода jQuery есть недостатки. См., Например, stackoverflow.com/questions/1915341/… . Кроме того, Джон Ресиг отнюдь не знает всего, что нужно знать о JavaScript, и вера в то, что он знает, не поможет вам как разработчику JavaScript.Типографская версия ответа @justin, совместимая с ES6, с использованием символов для предотвращения конфликта клавиш и добавленная в глобальный Object.id для удобства. Просто скопируйте и вставьте приведенный ниже код или поместите его в импортируемый файл ObjecId.ts.
Пример использования:
источник
Я использовал такой код, который заставит объекты объединяться с уникальными строками:
эти
__proto__
биты , чтобы сохранить__id__
геттер от просмотра в объекте. это было проверено только в firefox.источник
__defineGetter__
это нестандартно.Несмотря на совет не изменять Object.prototype, это может быть действительно полезно для тестирования в ограниченных пределах. Автор принятого ответа изменил его, но все еще настраивает
Object.id
, что для меня не имеет смысла. Вот фрагмент, который делает эту работу:источник
Я столкнулся с той же проблемой, и вот решение, которое я реализовал с ES6
источник
С целью сравнения двух объектов самый простой способ сделать это - добавить уникальное свойство к одному из объектов в тот момент, когда вам нужно сравнить объекты, проверить, существует ли свойство в другом, а затем удалить его снова. Это позволяет сэкономить на прототипах.
источник