В JS вы можете вернуть логическое значение, имеющее пользовательские свойства. Например. когда Modernizr проверяет поддержку видео, он возвращает true
или, false
но возвращенное логическое значение (Bool является объектом первого класса в JS), имеет свойства, определяющие, какие форматы поддерживаются. Сначала это меня немного удивило, но потом мне стала нравиться эта идея, и я удивился, почему она используется довольно редко?
Это выглядит как элегантный способ справиться со всеми этими сценариями, где вы в основном хотите знать, является ли что-то истинным или ложным, но вас может заинтересовать некоторая дополнительная информация, которую вы можете определить, не определяя пользовательский объект возврата или используя функцию обратного вызова, подготовленную для принять больше параметров. Таким образом, вы сохраняете очень универсальную сигнатуру функции без ущерба для возможности возврата более сложных данных.
Против этого есть три аргумента:
- Это немного необычно / неожиданно, когда лучше, чтобы любой интерфейс был понятным и не хитрым.
- Это может быть аргумент соломенного чучела, но, учитывая, что он является чем-то вроде крайнего случая, я могу себе представить, что в некоторых оптимизаторах JS, uglifier, VM или после незначительной смены спецификаций языка очистки и т. Д. Это может иметь неприятные последствия.
- Есть лучший - краткий, ясный и общий - способ сделать то же самое.
Итак, мой вопрос: есть ли веские причины избегать использования логических значений с дополнительными свойствами? Это трюк или удовольствие?
Участок крутит предупреждение.
Выше оригинальный вопрос в полной славе. Как указали Мэтью Крамли и Сеневольдсен, это основано на ложной (ложной?) Предпосылке. В традициях JS, что делает Modernizr, это языковой трюк и грязный. Это сводится к тому, что JS имеет примитив bool, который, если он установлен в false, останется ложным даже после того, как TRYING добавит реквизит (который завершается с ошибкой) и логический объект, который может иметь пользовательские реквизиты, но быть объектом всегда правдив. Modernizr возвращает либо логическое ложное значение, либо истинный логический объект.
Мой оригинальный вопрос предполагал, что уловка работает по-другому, и поэтому наиболее популярные ответы касаются (совершенно правильного) аспекта стандартов кодирования. Однако я считаю, что ответы, опровергающие весь трюк, наиболее полезны (а также основные аргументы против использования метода), поэтому я принимаю один из них. Спасибо всем участникам!
null
если не поддерживается, и массив форматов, если это так. Список считается правдивым в JS иnull
является ложным.Ответы:
В дополнение к общим принципам проектирования, таким как единая ответственность и наименьшее удивление, есть специфическая для JavaScript причина, по которой это не очень хорошая идея: существует огромная разница между JavaScript
boolean
иBoolean
JavaScript, которая мешает его работе в общем случае.boolean
является примитивным типом, а не объектом, и не может иметь пользовательских свойств. Выражения любятtrue.toString()
работать, потому что за кадром это превращается в(new Boolean(true)).toString()
.Boolean
(с большой буквы B) является объектом, но имеет очень мало хороших применений, и его использование какboolean
определенно не является одним из них. Причина в том, что каждыйBoolean
является «истиной», независимо от его значения , потому что все объекты преобразуютсяtrue
в логический контекст. Например, попробуйте это:Таким образом, в общем случае в JavaScript нет способа добавить свойства к логическому значению, которое по-прежнему позволяет ему вести себя логически. Modernizr может сойти с рук, потому что единственное добавление свойств к «истинным» значениям, которые работают, как вы ожидаете (т.е. они работают в операторах if). Если видео вообще не поддерживается, оно
Modernizr.video
будет действительнымboolean
(со значениемfalse
) и к нему не будут добавлены свойства.источник
true
приводит к условному условию. Зачем явно использоватьBoolean
?false
они оба являются «ложными» и ложными (===
и==
работают как), НО на самом деле вы не можете добавить реквизиты к примитивному bool. Различие между Bool и bool, по-видимому, ускользнуло от меня.TypeError
вы получите a, если попытаетесь добавить свойство (см. Jsbin.com/yovasafibo/edit?js,console ).Поздравляю, вы обнаружили объекты. Причиной этого не является принцип наименьшего удивления . Быть удивленным дизайном не очень хорошая вещь.
Нет ничего плохого в том, чтобы связать воедино эту информацию, но зачем вам ее прятать в Bool? Поместите это в то, что вы ожидаете получить всю эту информацию. Бул в комплекте.
источник
Основной аргумент , который я держать против него есть, единый принцип ответственности , булево должен сказать , только если что - то
true
илиfalse
, не то, почему или как и любая другая вещь. Я твердо убежден и практикую, что для передачи той или иной информации следует использовать другие объекты.источник
Boolean
Несмотря на махинации JavaScript .Поскольку причина, по которой оно называется логическим значением, заключается в том, что оно истинное или ложное, мне не нравится эта идея, поскольку вы в значительной степени подрываете ее цели из Википедии.
(мой смелый)
источник
То, что вы можете не означать, в JS вы можете в значительной степени присоединять свойства к любому объекту (включая логические значения)
Как это плохо?
С одной стороны, вы можете прикрепить больше не относящихся к делу данных к логическому значению (согласно вашему примеру), чего другой разработчик не будет ожидать, потому что зачем оно там ?! bools только для правды и лжи.
Для этого нужно добавить некоторые полезные свойства, которые могут помочь вам справиться с логическим значением (это делает Java ).
Например, вы можете прикрепить функцию, которая преобразует логическое значение в строку,
dirty
флаг, который стал истинным, если значение было изменено, наблюдатели и обратные вызовы событий, которые могут срабатывать при изменении значения и т. Д.Это звучит как что-то, что не следует хранить в логическом значении, а использовать набор логических значений или набор свойств с логическими значениями внутри них. Я думаю, что лучшим подходом было бы вернуть объект со всеми форматами и подробностями поддержки.
источник
Вы не можете создавать логические значения с пользовательскими свойствами в JavaScript. Следующий сбой (по крайней мере, в FF):
Вы можете использовать или наследовать от Boolean, но, как говорит Мэтью Крамли, это дает разные результаты.
Boolean
имеет типObject
. Когда JS требуется логическое значение выражения, оно преобразуется с помощью функции спецификацииToBoolean
, которая обязывает, что дляObject
s результат всегдаtrue
. Таким образом, значениеnew Boolean(false)
оценивается какtrue
! Вы можете проверить это в этом примере: https://jsfiddle.net/md7abx5z/3/ .Единственная причина, по которой он работает для Modernizr, - случайность. Они только создают
Boolean
объект, когда условие выполняется. Когда они оценивают ложь, они просто возвращают обычноеfalse
. Так что это работает, потому что они возвращаютBoolean
объекты только тогда, когда результат был истинным, и никогда, когда он ложный.источник
Я понимаю, что контекст изменился, но я хотел бы ответить на оригинальный вопрос, который я прочитал, используя JS в качестве примера, но не ограничиваясь только JS.
Добавление свойств к логическому значению не будет проблемой, если свойства имеют отношение к true / false, а не к переменной, содержащей значение. Например, было бы хорошо добавить метод toYesNoString, а добавление numberOfChildren к значению hasChildren - нет, равно как и questionsMissed studentPassed. Существует не так много, что вы могли бы добавить к логическому значению, кроме различных представлений строк, единственное свойство, которое я могу придумать, имеет смысл, это originalExpression. Но добавление к этому не обязательно плохая идея в теории.
источник
Если я смотрю на код, то речь идет не о булевых пользовательских свойствах, а о методе, имеющем методы возврата с разными сигнатурами.
Если это ложь, тогда вы получаете примитив ложь, и если это правда, он возвращает объект, который по определению интерпретируется как истина в JavaScript.
Так что, на мой взгляд, ваш вопрос должен состоять не в том, стоит ли давать логические пользовательские свойства, а в том, чтобы иметь методы с несколькими возвращаемыми сигнатурами.
источник
В данном примере, вы не могли бы просто вернуть массив всех поддерживаемых видеоформатов?
По крайней мере, я бы сказал, что использование массива несколько менее удивительно, чем использование «пользовательских логических значений».
В Javascript пустой массив даже считается ложным , в то время как непустой массив является правдивым , поэтому, если повезет, вы можете просто переключиться на массивы, и все будет работать так же, как и доредактирования Нет, глупо, я думаю, что могу вспомнить правдивость объектов в JavaScript: Pисточник
""
имеет typeof,"string"
но это на самом деле ложь[].length
ложь, если длина»0
, не намного больше печатает, и, на мой взгляд, является лучшим показателем намерения, чем простоif([])
было бы, даже если бы это сработало.