1

I am facing a weird scenario while playing with WeakMap in ECMA6. I am writing a class which is as follows

'use strict';
class WeekMaptest {

    constructor(options){
        console.log("constructor");
        this.weekMap = new WeakMap();
        this._init(options);
    }
    _init(options) {
        console.log("init called");
        var privateProps = {
            name: options.name,
            email: options.email
        };
        this.weekMap.set(this, privateProps);
    }

    getName(){
        return this.weekMap.get(this).name;
    }


}

Now calling this class to instantiate an object

var obj = new WeekMaptest({name: 'Rohit', email: 'rohit.choudhar@gmail.com'});

Here comes the out put

console.log(obj.getName());
Output : Rohit

console.log(obj.weekMap.get(obj).name);
Output : Rohit

console.log(obj.weekMap.set(obj).name = 'I mena');
Output : I mena

console.log(obj.weekMap);
Output: WeakMap { name: 'I mena' }

console.log(obj.weekMap.get(obj).name);
Error:
/home/bll/bll-jb/server/lib/ease/testweak.js:35
console.log(obj.weekMap.get(obj).name);
                                ^

TypeError: Cannot read property 'name' of undefined
    at Object.<anonymous> (/home/bll/bll-jb/server/lib/ease/testweak.js:35:33)
    at Module._compile (module.js:434:26)
    at Object.Module._extensions..js (module.js:452:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:475:10)
    at startup (node.js:117:18)
    at node.js:951:3

I am not able to get myself clear about this behavior of WeakMap.

Rohit Choudhary
  • 2,253
  • 1
  • 23
  • 34

1 Answers1

3

I guess you confused setand get.

console.log(obj.weekMap.set(obj).name = 'I mena');

Entries before this call: obj => obj

Entries after this call: obj => undefined

set expects arguments for key and value. You don't provide a value, so this code sets the value of the entry with the key obj to undefined. Consequently the next call to obj.weekMap.get(obj) returns undefined.

a better oliver
  • 26,330
  • 2
  • 58
  • 66
  • So the question is variable defined using WeakMap inside class are actually not Private? – Rohit Choudhary Nov 02 '15 at 09:10
  • @RohitKumarChoudhary I don't know what you mean by _"variable defined using WeakMap"_. – a better oliver Nov 02 '15 at 11:41
  • @RohitKumarChoudhary If you are referring to `privateProps` then that's a variable that is only visible within `_init`. But the reference it holds is passed to the outside through the weak map. If you are referring to the weak map then nothing is private there. – a better oliver Nov 03 '15 at 07:53
  • Your explanation about weakMap is correct and I know about closure, but my question is why people are suggesting to make private properties using weakMap? . Thank you for your answer, – Rohit Choudhary Nov 03 '15 at 11:26
  • @RohitKumarChoudhary Now I understand what you want to achieve. You would have to declare a weak map outside the class and add your "private" properties with the instance of the class as key, as you already did. When the object is "deleted" (i.e. no longer referenced) the entry in the weak map is removed automatically. With a regular map the entry would remain and therefore the instance cannot be garbage collected, which effectively creates a memory leak. – a better oliver Nov 03 '15 at 11:47