Как определить публичное свойство в классе javascript?

1

С помощью конструктора ES5 и прототипа я могу добавить общедоступные (прототипы) свойства, как показано ниже:

function Utils(){}
Utils.prototype.data = {};

var utils = new Utils();
console.log(utils.data);  //{}

ES6 class позволяет мне определить только открытые методы в классе. Я создаю приложение с классом-подход, и я не хочу смешивать конструкторы и классы. Рабочий код, который я выяснил, это:

class Utils(){
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}

const utils = new Utils();
console.log(utils._data); //{}

Когда я _data метод _data getter, он проверяет, существует ли свойство _data в объекте прототипа. Если это так, оно возвращает его, иначе оно инициирует свойство _data.

Это хорошая практика? Есть ли другой способ сделать это лучше?

  • 0
    Почему вы не хотите инициализировать свойство данных в конструкторе класса ES6? Глядя на документацию, кажется, что именно так MDN делает это.
  • 0
    Свойства экземпляра создаются с помощью this (то есть this.data = ... ).
Показать ещё 2 комментария
Теги:
class

2 ответа

0

Я не знаю, является ли код, который вы предоставили, вашим полным кодом или нет, но когда я его запускаю, он выдает ошибку:

class Utils {
  get _data(){
    const proto = Object.getPrototypeOf(this);
    if(!proto._status) proto._data = {};
    return proto._data;
  }
}


/* TEST */
const a = new Utils();
a._data.ok = 'ok';

const b = new Utils();
console.log(b._data.ok);

Если я правильно вас понимаю, вы хотите, чтобы все экземпляры Utils использовали одно и то же свойство data.

Есть несколько способов, которые я могу придумать, чтобы делать то, что вам нужно, но он может "смешивать конструкторы и функции классов" (я не понимаю, что вы подразумеваете под этим).

1: Добрый путь ES5

class Utils {}
Utils.prototype.data = {};

/* TEST */
const a = new Utils();
a.data.ok = 'ok';

const b = new Utils();
console.log(b.data.ok);

2: То же, что и ваш путь, но в нем конструктор

class Utils {
  constructor(){
    if (!this.data)
      Utils.prototype.data = {};
  }
}

/* TEST */
const a = new Utils();
a.data.ok = 'ok';

const b = new Utils();
console.log(b.data.ok);

Хотя, поскольку свойство data необходимо обменивать между экземплярами, я предлагаю вам добавить свойство к его прототипу с использованием метода Object.defineProperty чтобы сделать его неприемлемым и неудобным:

Object.defineProperty(Utils.prototype, 'data', {
    value: {},
    writable: false,
    enumerable: true,
    configurable: false
});

Это необходимо для того, чтобы свойство данных нельзя было переназначить или удалить, что минимизирует вероятность ошибочного сброса данных или т.д.

Я бы порекомендовал первый способ (с Object.defineProperty), потому что это:

  1. Больше надежной
  2. Яснее
  3. Легче поддерживать
0

Чтобы сделать data общедоступными:

class Utils {
  constructor () {
    this.data = {}
  }
}

Чтобы сделать data общедоступными статическими свойствами, get/set, вероятно, лучший способ:

let data = {}
class Utils {
  get _data () {
    return data
  }
  set _data (d) {
    data = d
  }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню