2

I want to set my class properties private so I used WeakMap but with a single WeakMap. After my items creation, I get only the last object data, previous data are deleted...

This is my code definition:

const Item = (() => {
  const weakMap = new WeakMap();
  const _id = {};
  const _text = {};

  class Item {
    constructor({id, text}) {
      weakMap.set(_id, {id});
      weakMap.set(_text, {text});
    }

    getId() {
      return weakMap.get(_id).id;
    }

    getText() {
      return weakMap.get(_text).text;
    }
  }

  return Item;
})();

Here I create an array with all my items:

const items = myItems.map(item => {
  const newItem = new Item(item);
  console.log('new item created, id: ' + newItem.getId());
  return newItem;
});

The items are well created, I get:

new item created, id: 1
new item created, id: 2
new item created, id: 3
new item created, id: 4

But when I iterate on my items I get:

items.forEach(element => console.log(element.getId() + ' ' + element.getText()));

4 Fourth description
4 Fourth description
4 Fourth description
4 Fourth description

This is a live example: https://plnkr.co/edit/pFCOcCVl1AQEJqSKvfVX

Also with closure it's not working:

const Answer = (() => {
  const weakMap = new WeakMap();
  const _id = {};
  const _text = {};

  class Answer {
    getId;
    getText;

    constructor({id, text}) {
      weakMap.set(_id, {id});
      weakMap.set(_text, {text});

      this.getId = () => weakMap.get(_id).id;
      this.getText = () => weakMap.get(_text).text;
    }
  }
}
Fred
  • 2,965
  • 4
  • 29
  • 51
Hazlo8
  • 565
  • 8
  • 27

1 Answers1

2

If you use a WeakMap to implement private properties, the key in the map is usually the object/instance itself. The value is an object that holds all the private properties.

const Item = (() => {
  const weakMap = new WeakMap();

  class Item {
    constructor({id, text}) {
      const privateData = {id, text};
      weakMap.set(this, privateData);
    }

    getId() {
      return weakMap.get(this).id;
    }

    getText() {
      return weakMap.get(this).text;
    }
  }

  return Item;
})();
Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
  • What is the point of using such complicated structure in JavaScript in real life? – eugsun Mar 03 '20 at 14:09
  • @Felix thanks, so I can set one single object for each WeakMap. – Hazlo8 Mar 03 '20 at 14:11
  • 2
    @EugenSunic: TBH I don't know. But I assume if there weren't use cases for private properties, there wouldn't be a proposal for adding them. https://github.com/tc39/proposal-class-fields#private-fields – Felix Kling Mar 03 '20 at 14:34