Pull to refresh

Comments 23

Мне кажется, что для приватных полей надо использовать Symbol, не? Они же как раз для этого в стандарт внедрялись вроде.
Символы — уникальные ключи, а не приватные. Их можно получить через Object.getOwnPropertySymbols, Reflect.ownKeys, скопировать через Object.assign. Их задача — предотвращение перекрытия свойств в пользовательском коде. Впрочем WeakMap тоже не является полностью приватным — при желании можно вытащить дынные, обернув методы прототипа коллекции. По идее, настоящие приватные поля могут появиться в ES7.
Да конечно их можно использовать в некотором роде. Но мы полностью не спрячем такие поля. Символы могут быть получены с помощью методов Object.getOwnPropertySymbols и Object.getOwnPropertyKeys.

UPD. Выше меня опередили.
Нет такого метода Object.getOwnPropertyKeys и не планируется.
Это внутренний метод, который используют Object.getOwnPropertyNames и Object.getOwnPropertySymbols. А метода Object.getOwnPropertyKeys нет и не планируется.
Но мы полностью не спрячем такие поля

Я никогда не понимал: а зачем? Это ведь должно быть как соглашение, как помощь программисту. Откуда маниакальное желание физически скрыть их, сделать абсолютно невозможным доступ? Как отлаживать такой код, если не можно в дебагере посмотреть значения приватных свойств? Тем более, что часто гараздо полезнее именно протектед модификатор, а не приват.
Зачем вы из Javascript пытаетесь сделать язык, на которым вы писали до этого? Не надо пытаться запихать в js приватные поля или классическое ООП. Перестаньте. Пользуйтесь идиоматичными подходами, которые и делают javascript таким интересным: замыкания, литералы обьектов и фабричные методы и Object.create/Object.assign.
Инкапсуляция.
Подход приведенный в публикации активно используется индженерами в мазиле. Например Антон Ковалев использовал его при сокрытии нижнего слоя редактора. Для чего? Они не хотели показывать пользователям их API, что у них под капотом CodeMirror. Не из соображений сокрытия реализации, а из за соображений того, что они могут его свободно обновлять, изменять, или сменить полность на другой. Без страха сломать сторонние плагины под CodeMirror, что черевато крахом продакшена
Замыкания полностью решают задачи инкапсуляции. При этом такой подход остается «типичным» для javascript, идиоматичным, если хотите. Посмотрите как сделана основная масса крупных и известных библиотек, там есть очень много интересного на эту тему.

Попытка же сделать приватные поля в виде java-образного ООП приводит к грязным хакам и корявым решениям.
Инкапсуляция

Вы не понимаете смысл, дух инкапсуляции. Инкапсуляция — это не модификаторы «private» и «protected». Инкапсуляция — это сокрытие реализации за интерфейсом. Это когда вы смотрите на метод "findItems()" и не задумываетесь, какой код он вызывает, какие публичные или приватные методы дергает, главное, чтобы он соблюдал соглашение (интерфейс). Инкапсуляция неразрывно связана с, например, полиморфизмом, где метод изменяется, оставляя старое соглашение, но за счет инкапсуляции вас не интересует, что именно внутри него.

А модификаторы private и protected — не более чем сахар и не являются обязательными для инкапсуляции.
Так именно это я и имел ввиду. Но — инкапсуляция это не только сокрытие реализации. Она так же может преследовать следующие цели:
Организовать доступ пользователя к атрибутам и методам так, чтобы предотвратить несанкционированное использование (у нас пока нет интерфейсов, но есть необходимость).
Защита от ошибок программиста заключается в неразрешенных объектах, способах использования методов (атрибутов).

Концептуальная модель ООП предполагает 2 области видимости: — методы видны для всех пользователей класса — методы видны только для объектов данного класса.

Для кого-то это важно, для кого-то нет. JS является решением множества проблем. И есть ряд задач где сокрытие как данных так и реализации необходимы в равной степени. Я привел отличный пример выше.
> Одно из самых больших упущений JavaScript это невозможность создания приватных полей в пользовательских типах.

Почему это упущение? Никогда не страдал по этому поводу, что в Питоне, что в Джаваскрипте.
Оффтопик: не укора ради, а просто интересно, почему про Python таких статей не появляется? Про JS на одном только хабре каждые полгода кто-нибудь изобретает приватные поля.
UFO just landed and posted this here
Спасибо, познавательно. Только недавно задумывался над тем как реализовать приватные свойства, чтоб были видны в конструкторе и прототипах, но не извне.
Приватные свойства? В прототипах? Оригинально!
Да, спасибо, но такой подход и мне в голову пришел, я не захотел заниматься «выносом кишок» из конструктора и дублировать методы (публичный -> прототип).

Вариант с объектом в замыкании мне нравится больше, конструктор выглядит чище, необходимо всего лишь не забывать удалять личные данные из объекта при убивании инстанса.
В ES7 этих proposal-ов приватных свойств чуть ли не больше чем реализаций классов на JS.
Вот, например, что в свое время поддерживал babel как экспериментальную фичу (уже нет)
class Pos {
    @x;
    @y;
    constructor(x,y){
        @x = x;
        @y = y;
    }
}


Как раз на викмапах работало. Что тоже не очень честно. Можно сделать паблика морозова при желании.

А вообще — если серьезно — ну не надо этой приватщины в джаваскрипте. Есть договоренность о том, что свойства с _ в начале — приватные и никто в них не лезет. И всем хорошо. Дебажить удобнее, работать удобнее, никакого геммороя.
Серьёзно больше? Что-то не наблюдаю :) Этот синтаксис не поддерживался babel. Поддерживались абстрактные ссылки и ключевое слово private, в том числе и в литерале класса, как сахар для WeakMap (хотя для этого дела изначально планировались специальные PrivateMap), но Kevin Smith разделил предложение на 2 куда более узкие и, с моей точки зрения, не такие удачные части — private fields (ссылку на которые привёл выше) и bind operator.
Я образно. Но штук 10-20 точно были и есть.

Про пример — да, извиняюсь, this::x поддерживался, а не @x, перепутал.

Не было 10 и уж тем более для ES7. Хотя не суть важно.
Sign up to leave a comment.

Articles