开发者

What are ECMAScript 6 WeakMaps?

After reading this description: http://wiki.ecmascript.org/doku.php?id=har开发者_开发百科mony:weak_maps

I'm trying to get a hang of it, but I do not get the overall picture. What is it all about? It seems to be supported in Firefox 6: http://kangax.github.com/es5-compat-table/non-standard/


A weak reference is a special object containing an object-pointer, but does not keep that object alive.

One application of weak references are implemented in Weak Maps:

“The experienced JavaScript programmer will notice that this API could be implemented in JavaScript with two arrays (one for keys, one for values) shared by the 4 API methods. Such an implementation would have two main inconveniences. The first one is an O(n) search (n being the number of keys in the map). The second one is a memory leak issue. With manually written maps, the array of keys would keep references to key objects, preventing them from being garbage collected. In native WeakMaps, references to key objects are held “weakly”, which means that they do not prevent garbage collection in case there would be no other reference to the object.” Source

(See also my post when ECMAScript Harmony was first released with Firefox... )


WeakMap

WeakMaps basically allow you to have a HashTable with a key that isn't a String.

So you can set the key to be, i.e. [1] and then can say Map.get([1])

Example from the MDN:

var wm1 = new WeakMap(),
    wm2 = new WeakMap();
var o1 = {},
    o2 = function(){},
    o3 = window;

wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // a value can be anything, including an object or a function
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // keys and values can be any objects. Even WeakMaps!

wm1.get(o2); // "azerty"
wm2.get(o2); // undefined, because there is no value for o2 on wm2
wm2.get(o3); // undefined, because that is the set value

wm1.has(o2); // true
wm2.has(o2); // false
wm2.has(o3); // true (even if the value itself is 'undefined')

wm1.has(o1);   // true
wm1.delete(o1);
wm1.has(o1);   // false

The reason for its existance is:

in order to fix a memory leak present in many uses of weak-key tables.

Apparently emulating weakmaps causes memory leaks. I don't know the details of those memory leaks.


WeakMap allows to use objects as keys. It does not have any method to know the length of the map. The length is always 1. The key can't be primitive values

A word of caution about using object as key is, since all the objects are by default singletons in JavaScript we should be creating an object reference and use it.

This is because when we create anonymous objects they are different.

if ( {} !== {} ) { console.log('Objects are singletons') };
// will print "Objects are singletons" 

So in the following scenario, we can't expect to get the value

var wm = new WeakMap()
wm.set([1],'testVal');
wm.get([1]);  // will be undefined

And the following snippet will work as expected.

var a = [1];
wm.set(a, 'testVal');
wm.get(a); // will return 'testVal'   
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜