Классы JavaScript - делайте переменные приватными с WeakMap и все еще используя «this» в других методах - PullRequest
0 голосов
/ 19 ноября 2018

Я читаю книгу "Изучение JS DataStructs и алгоритмов", и в книге говорится, что "элементы" являются общедоступными в следующем классе.

class Stack {
    constructor(){
      this.items = []
    }
 }

Но, если я использую WeakMap, я могу снова сделать элементы приватными, только в примерах, учитывая, что они не используют «this», как я ожидал.

const items = new WeakMap();
class Stack {
    constructor(){
      items.set(this, []);
    }
}

, а затем приводятся примеры кода, который выполняет такие вещи, как items.set или items.get для доступа к вещам, и это выглядит нормально, но мне было интересно, могу ли я просто сократить доступ к item.get (value) в Конструктор на «это» выглядит так:

const items = new WeakMap();
class Stack {
    constructor() {
        items.set(this, []);
        this.stack = items.get(this, []);

     push(item) {
         this.stack.push(item)
     }
}

Теперь я могу получить доступ к функционалу items.get () с помощью this.stack, но я НЕ уверен, что он снова станет публичным, и мне было интересно, может ли кто-нибудь помочь мне разобраться с этим?

1 Ответ

0 голосов
/ 19 ноября 2018

Да - любое свойство this фактически является публичным. Итак, если у вас есть this.stack, а stack относится к массиву, этот массив будет доступен для просмотра и изменения из всего, что имеет доступ к созданному объекту, что вам, вероятно, не нужно.

Обратите внимание, что даже во втором фрагменте кода использование items WeakMap недостаточно для того, чтобы сделать данные личными - например, все, что имеет доступ к items и для экземпляра объекта может изменить массив для этого элемента:

const items = new WeakMap();
class Stack {
  constructor() {
    items.set(this, []);
  }
}

const s = new Stack();
items.get(s).push('foo');
console.log(items.get(s));

Чтобы исправить это, можно было бы поместить все это в IIFE с items scoped в пределах IIFE, а затем вернуть класс:

const Stack = (() => {
  const items = new WeakMap();
  return class Stack {
    constructor() {
      items.set(this, []);
    }
  };
})();
const s = new Stack();
// now, items can only be seen and modified through Stack's internal methods
...