2013-05-03 12 views
18

Я столкнулся с JavaScript library, которые реализуют кросс-браузер WeakMap в ES5. (WeakMap рассчитан на ES6.)Реализация WeakMap в EcmaScript5?

Как это возможно работать без поддержки на языке JavaScript?

Edit: Просто чтобы быть ясно, я имею в виду на Слабое Карта, не обычная карта. Я протестировал этот проект с использованием профилировщика Chrome, и ключи не поддерживаются сильными ссылками. Они получают GC'ed, не снимая их с WeakMap.

+3

Рассмотрите возможность изучения исходного кода. – 2013-05-03 19:17:05

+3

@squint Это делает что-то довольно глубокое - я не могу понять, как он не держит сильную ссылку на клавиши. Например, он не использует массивы. – paleozogt

+3

WeakMaps - это функция ES6, которая позволяет связать данные с объектом, но все же пусть эти данные собираются в мусор, когда либо объект -OR- сам экземпляр WeakMap является собранным мусором. Это невозможно сделать без поддержки языков. Большинство прокладок WeakMap игнорируют часть, позволяющую передавать данные GC'd, когда сам экземпляр WeakMap является GC'd. – AgentME

ответ

26

Мне понадобилось некоторое время, чтобы получить код, но потом он ударил меня: сам ключ используется для хранения ссылки на значение.

Например, несколько слоев в set он делает

defProp(obj, globalID, { value: store }); 

, где defProp был определен, чтобы быть Object.defineProperty, obj является ключом, globalID является GUID и store является объектом хранения, который содержит значение.

Тогда вниз в get он ищет значение с

obj[globalID];

Это очень умный. В WeakMap фактически нет ссылки на что-либо (слабое или иное) - он просто устанавливает политику, в которой тайно хранить значение. Использование Object.defineProperty означает, что вы случайно не обнаружите хранилище значений - вы должны знать волшебный указатель, чтобы посмотреть его.

Поскольку ключ напрямую относится к значению (и ссылка WeakMap не ссылается на него), когда все ссылки на ключ исчезли, он получает GCed, как обычно.

+0

Если 'obj' - это ключ WeakMap, а' globalID' определен в 'obj', мне интересно, почему' globalID' не появляется при использовании 'Object.getOwnPropertyNames()'. – 2013-05-03 21:58:41

+2

Мне было интересно то же самое; слишком плохо, что lib до сих пор остается за собой, чтобы быть практически нечитаемым. должно быть более простое объяснение ... – dandavis

+0

выяснил: читы lib: он переопределяет Object.getOwnPropertyNames(). boo для перехода на существующие нативные функции. – dandavis