Comments 61
З.Ы. Кажется, я где-то уже видел JS классы на викмапах, но искать лень.
var Archive = Class.create(null, SortableMixin, function ($public, $protected, _) {
$protected.init = function () {
_(this).data = [3, 9, 7, 2];
};
$public.outData = function () {
console.log(_(this).data);
};
});
то «у Билла» (который на картинке) в typescript все это (кроме множественного наследования) есть и работает проще и выглядит красивее (код разрабатываемого приложения, а не самого компилятора).
Лучше уж выучить TypeScript, чем чужую библиотеку где классы создаются через Class.create(null, SortableMixin, function ($public, $protected, _) {
Зачем тогда protected, если не для соблюдения инкапсуляции?
Все это не наезда ради, просто хочется разобраться, для чего может потребоваться данная библиотека и чем она лучше других решений, помимо бонуса множественного наследования (сомнительного, на мой взгляд).
Согласен, что для тех, кто пишет на TypeScript всё это не нужно.
Вам этот приват и протектед что в итоге дали? Отладку упростили? Среда разработки подчёркивает ошибки в именах методов?
Пример с примесями странный. Как отнаследоваться и примешать две примеси?
Да, вообще все делали такое.
Лет пять-десять назад.
Я потом я сделал над собой усилие и перешёл на TypeScript.
У реализации приватных полей через WeakMap есть две проблемы. С циклическими ссылками и с просмотром значений "полей" в отладчике.
Почему вы не стали использовать символы?
var SomeClass = function() {
var privateSymbol = Symbol("privateData");
function SomeClass(value) {
this[privateSymbol] = value;
}
SomeClass.prototype[privateSymbol] = 0;
SomeClass.prototype.someMethod = function () {
return this[privateSymbol];
}
return SomeClass;
}()
Вот так символ выглядит в консоли Хрома:
![](https://habrastorage.org/files/00d/204/3f9/00d2043f9ff64aaab975dab636558c6f.png)
del
Велосипед, конечно, богатый, с кучей возможностей. К сожалению, недостатки у него такие же, какие были у всех остальных:
- Каждый фреймворк юзал свою такую вот библиотечку, стандарта де факто (как с jQuery) не получилось
- Поддержка в IDE, в силу динамической природы трюка, никакая, а в рантайме все эти private/protected ни к чему
Присоединюсь к советующим посмотреть на TypeScript.
Уиии, 2017 год, а добрая традиция, или даже лучше сказать дисциплина, «пишем свои классы в JS» до сих пор живет!
Много лет назад я знакомился с php и меня выбесило отсутствие в нём перегрузки арифметических операций, как в C++. Я посчитал такое ООП неполноценным и забросил сей язык. Забросил не только поэтому, но этот эпизод стал важной последней каплей. Такие вот превратности судьбы.
Так же, как private/protected:)
Предложите в каком-нибудь сообществе типа java или php отказаться от private/protected — вам покрутят у виска. В JS-сообществе же с точностью наоборот.
А предложите в питоньем сообществе private/protected — покрутят точно так же. Вопрос привычки и удобства, реальной необходимости ни в перегрузке, ни в сокрытии нет.
a.add(b); // a, b - операнды
или так
mat.add(a, b); // mat - объект, играющий роль неймспейса
а могла бы вот так
a + b
Да, понятно, что так красивее и удобнее и приятнее, и мне тоже не хватает иногда перегрузки операторов в JS. Но решающей принципиальной разницы нет, далеко не в каждой задаче есть матрицы или комплексные числа.
a * b — это векторное, скалярное или поэлементное умножение?
Речь о том, что перегрузка операторов без возможности объявления своих операторов — так себе решение. Чего только стоит перегрузка битового сдвига (<<) для стримов в C++.
Чего только стоит перегрузка битового сдвига (<<) для стримов в C++.
Вы так говорите, будто это что-то плохое.
В случае с protected — соглашусь, но вот private… Никто не мешает использовать процедурный или функциональный язык, где private определяет наличие или отсутствие какой-то структуры (например функции) при экспорте модуля.
… Ничего не напоминает? Модификаторы доступа — это лишь одна из возможностей реализации инкапсуляции, в JS инкапсуляция реализуется наличием/отсутствием кейворда export, например. Замените export на public, а его отсутствие на private, вот и получаем ту же самую инкапсуляцию на уровне модулей, а не на уровне класса/объект, что, к слову, местами профитнее (код интерфейса (не interface, а публичной части) тупо чище).
А давайте не будем принимать совпадения за закономерности? Сегодня "вне объектного подхода" таких ключевых слов нет — а завтра кто-нибудь придумает новый чистый функциональный язык программирования, где эти слова будут присутствовать.
Не надо так.
Ну не правда же, я просто провёл параллель с JS и намекнул, что private есть и в JS, просто он иначе называется и иначе работает, а заодно сделал намёк, что этот "private" есть и в других не ОО языках, иногда даже так и называется, например в Ada или Fortran
UPD. И согласился по поводу protected, т.к. не припомню не ОО языков, где был бы подобный модификатор, хотя придумать можно.
Весь остальной флуд меня изумляет своей беспочвенностью =)
Ну с моей стороны диалог выглядит так (насколько я его понял):
- Доминик: У каждого языка, мол, свои плюшки, мне, например, не понравился ООП в пыхе, т.к. там нет перегрузки операторов.
- Вы: Перегрузка операторов — это не ООП
- k12th: Так статья тоже не про ООП, а просто частности переноса одного в другое
- Вы: Да ладно, модификаторы как раз про ООП.
А дальше моё замечание, мол, ну почему же. Если я кого-то не совсем правильно понял, прошу понять и простить =)
Мало вам классов в JS берите Dart там есть все и даже больше, без вот этих ваших костылей и прочего.
Из реальных альтернатив только TypeScript, с его реализацией всего этого дела на этапе компиляции.
Согласен, что велосипед и очередная библиотека. Лично для меня весь этот проект — показатель того, что на чистом JS можно реализовать настоящий protected, пусть и несколько нетривиально.
Я так и не понял зачем вам настоящие приватные и защищенные методы в js? Для контроля кода в момент разработки достаточно писать jsdoc и тогда нормальная IDE сама сообщит что это за метод и как его следует использовать. Для иллюзии защищенности кода в момент выполнения, так это только иллюзия и лишнее переосложнение системы, еще не раз будет напоминать себе при отладке.
Другое дело, что JS из коробки это не предоставляет, а обходные пути либо сложные (как представлено здесь), либо работают только в определённой среде (предупреждения IDE, ошибки компиляции TypeScript). Проблема в том, что большинство библиотек написаны на чистом JS, а не на TypeScript. И не факт, что все работают в IDE с соблюдением всех рекомендаций.
Если вы хотите, чтобы вам компилятор жаловался, что вы обращаетесь к private/protected полю снаружи, так это вам компилируемый язык нужен, при чем тут JS-то вообще?
Ну почему все пытаются воткнуть в JS ООП (в терминах Java/C++)? Тут прототипное наследование.
Потому что прототипное наследование в реализации JS — это грусть и погибель для поддержки более или менее сложных приложений, очевидно. Тренд в JS сейчас — это спрятать реальный, злой JS поглубже, обложившись разного рода трансляторами.
Если кому-то не нравится ASM, то он на нем и не пишет, с js тоже самое.
В чем проблема? Просто не пишите на js
Проблема в том, что не писать на js в некоторых областях — удовольствие того же уровня, что и писать на нем. Как такой код дебажить, например? Производительности это так же не добавит, ибо js — это совсем не asm.
транс-компилируемых языков
Транслируемых же, на выходе обычный текст.
Мое мнение все же останется прежним, что правильней это помечать jsdoc`ом приватные/защищенные методы, чем реализовывать это через библиотеки.
Что касается сторонних библиотек, то это проблема библиотек что там комментариев к коду нет, значит библиотека «не очень» и лучше воздержаться от ее использования.
Что касается IDE то не надо думать о всех, нужно думать о себе. Настройте IDE что бы оно понимало jdoc, помечайте методы jsdoc'ом, а те кто пишут в блокноте должны либо читать ваш код и помнить головой где какой метод или использовать IDE.
Так же можно ввести договоренность в именовании методов, например:
Методы которые начинаются на "$" это приватные, а "$$" это защищенные.
И это во много раз проще в поддержке и отладке, чем копаться потом в стектрейсе который будет захламлен библиотечными функциями.
Так же это проще для стороннего человека, ему не нужно въезжать в детали реализации библиотеки, достаточно только узнать о принятой методологии именовании методов.
Классы на JS с protected, множественным наследованием, геттерами/сеттерами и примесями