Являются ли частные свойства класса ES6 просто синтаксическим сахаром?

Используя синтаксис #, теперь мы можем создавать частные свойства в классах ES6 следующим образом:

class Person {
    #name;
    constructor(name) {
        this.#name = name;
    }
    getName() { return this.#name; }
}

let ron = new Person('ron')
ron.#name // undefined
ron.getName(); // ron

Ранее, в ES5, частные свойства вряд ли можно было «подделать» следующим образом:

function Person(name) {
  var name = name;
  this.getName = function() {
    return name;
  }
}
(new Person('ron')).name // undefined
(new Person('ron')).getName() // ron

В приведенной выше версии используется тот факт, что «var» не будет принадлежать «this» экземпляров Person. Таким образом, используя силу «замыкания», getName получает доступ к «имени». Однако проблема в том, что this.getName() не является частью цепочки прототипов, поэтому, чтобы добавить getName в прототип, нам нужно будет сделать:

Person.prototype.getName = function() { return this.getName(); }

Что сбивает с толку и довольно плохо пахнет.

Другой вариант: (используя символы ES6 и все еще не используя классы)

function Person(name) {
  const nameSymbol = Symbol();
  this[nameSymbol] = name;
  this.getName = function() {
    return this[nameSymbol];
  }
}

Но все еще не решает проблему, что getName не является частью прототипа. Другая проблема заключается в том, что с помощью Object.getOwnPropertySymbols этот «поддельный» частный член доступен.

Другой вариант es5 будет заключаться в использовании «шаблона модуля Revleaing» и предоставлении публичного API следующим образом:

const myEs5Module = (function () { 
  var _name = 'yos';
  function getName() {
    return _name;
  }
  const publicAPI = { getname };
  return publicAPI;
})();

Но это не класс или функция-конструктор, это больше похоже на модуль.

Поэтому я хотел бы понять, является ли синтаксис '#' для частных свойств в классах ES6 синтаксическим сахаром и может ли он быть каким-то образом полифиллен для таких любителей функций, как я.

Кстати: я читал сообщения вроде следующего: Частные свойства в классах JavaScript ES6 и до сих пор чувствую себя неудовлетворенным. также ПРИМЕЧАНИЕ. Я не ищу модули ES6 / решение Babel.

Все, что связано с классами в JS, — это «синтаксический сахар»

andy mccullough 21.12.2020 09:58

Частные свойства являются полифидируемыми, но дело в том, что если вы зарегистрируете экземпляр класса в отладчике, вы можете увидеть даже его частные свойства.

Akxe 21.12.2020 10:00

@andymccullough - Раньше это было правдой, до частных свойств и методов, но теперь это не так.

T.J. Crowder 21.12.2020 10:01

@andymccullough Являются ли классы ES6 просто синтаксическим сахаром для прототипа шаблона в Javascript?

adiga 21.12.2020 10:05
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
5
4
1 421
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
Являются ли частные свойства класса ES6 просто синтаксическим сахаром?

Нет. Они являются фундаментальным дополнением к тому, как объекты работают на внутреннем уровне. Частные поля (как они называются) хранятся в новых слотах в объекте, которых не было до предложения, и недоступны другими способами.

Поэтому я хотел бы понять, является ли синтаксис '#' для частных свойств в классах ES6 синтаксическим сахаром и может ли он быть каким-то образом полифиллен для таких любителей функций, как я.

Вы не можете использовать частные свойства без синтаксиса class. (Будущие предложения могут изменить это.) Вместо этого вам придется продолжать делать то, что вы делаете (решение закрытия), или использовать WeakMap только ваши функции имеют доступ к объекту, к которому относятся свойства.

Вы сделали свои собственные примеры закрытия, так что вот ваш класс Person, использующий подход WeakMap вместо частных свойств:

const Person = (() => {
    const names = new WeakMap();
    function Person(name) {
        names.set(this, name);
    }
    Person.prototype.getName = function getName() {
        return names.get(this);
    };
    return Person;
})();

let ron = new Person("ron")
console.info(ron.name);      // undefined
console.info(ron.getName()); // "ron"

FWIW, я подробно рассматриваю частные поля (и некоторые другие class функции, которые, вероятно, перейдут на этап 4 ["завершенные"} в этом году) в моей недавней книге JavaScript: The New Toys в главе 18. Ссылки в моем профиле если вы заинтересованы.

T.J. Crowder 21.12.2020 10:17

Это очень полезный ответ и фантастический бонус к моему пониманию. Большое спасибо.

Eva Cohen 21.12.2020 13:32

Я чувствую необходимость еще кое-что прояснить. Я вижу, вы использовали WeakMap с ключом this и значением name. так что каждый экземпляр будет иметь свое собственное «имя» по мере необходимости. Но как насчет: const Person = (() => { let _name = null; function Person(name) { _name = name; } Person.prototype.getName = function getName() { return _name; }; return Person; }) ; const PersonFactory = function(name) { const PersonMaker = Person(); вернуть новый PersonMaker (имя); }

Eva Cohen 21.12.2020 13:52

Я предложил не IIFE, а просто функциональное выражение. Извините или форматирование кода, которое могло вас запутать. Я протестировал его, и он создает разных Мэри и Джо.

Eva Cohen 21.12.2020 15:08

@EvaCohen - Извините, прочитал слишком быстро. Но это намного сложнее, чем вам нужно, и каждый раз, когда вы создаете экземпляр, создается совершенно новый Person (и Person.prototype), ничего не используя повторно. Вам лучше просто использовать функцию Person из второго блока кода в вашем вопросе и напрямую закрыть параметр.

T.J. Crowder 21.12.2020 15:34

Другие вопросы по теме