Неужели проверка на истинную простоту плоха по замыслу? - PullRequest
19 голосов
/ 19 января 2011

Считается ли плохим явно проверять логическое значение true.Было бы лучше сделать простой if(success)?

Я видел множество анекдотов о том, что if (someBoolean === true) ужасный код в строго типизированном языке, но считается ли он плохим в слабо типизированных языках?

Это применимо к любому слабо типизированному языку, который выполняет приведение типов в операторе if.

Конкретным примером будет:

var onSuccess = function (JSONfromServer) {
    // explicitly check for the boolean value `true`
    if (JSONfromServer === true) {
         // do some things
    }
}

// pass it to an ajax as a callback
doSomeAjax(onSuccess);

[Edit]

В данном конкретном случае переменная успеха - это любой допустимый JSON, возвращенный с сервера.Так что это может быть что угодно.если это логическое значение true, то успех случился.Если это какой-то объект обработки ошибок, то он будет обработан.Если это что-то еще, то, вероятно, будет обработано незаметно.

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

Хотелось бы избежать специфичности для JavaScript и AJAX.

Ответы [ 7 ]

17 голосов
/ 19 января 2011

С Javascript стоит знать, что помимо логических значений true и false, значения могут быть truey и falsy .

Учитывать:

if (false)     // evaluates to false.
if (0)         // evaluates to false, 0 is falsy.
if ("")        // evaluates to false, empty strings are falsy.
if (null)      // evaluates to false, null values are falsy.
if (undefined) // evaluates to false, undefined values are falsy.
if (NaN)       // evaluates to false, NaN is falsy.

Все остальные значения для объектов являются правдивыми.

Если истинные и ложные значения приводят к ошибкам в вашей логике, вы должны явно использовать операторы === и !==, чтобы обеспечить сравнение объектов по типу и значению.

12 голосов
/ 19 января 2011

Я сам в этом разбираюсь.

С одной стороны, пример кода, который вы разместили, хорош, потому что Javascript обрабатывает приведение типов. Простой if (success) будет вводить блок if, если success равен truey - например, непустая строка сделала бы случай. Тройное равенство гарантирует, что success действительно является логическим значением true, что является более сильной гарантией, чем вы получили бы с более короткой версией (и, вероятно, той, которая вам нужна).

Однако, если вам нужен , то есть, то есть вы не знаете, будет ли success логическим, или строкой, или целым числом, - я бы сказал, что это запах кода сам по себе. Независимо от того, как вы выполняете сравнение, я всегда сравнивал бы с переменной, которая неизбежно будет логическим значением; в этот момент не имеет значения, какая форма сравнения используется, поскольку они будут эквивалентны. На самом деле, я бы даже ввел «избыточную» переменную примерно так:

var successCount = items.size(); // or some other way to get an integer
var success = successCount > 0;
if (success) {
   ...
}

Итак, да. Я не думаю, что кто-то может действительно жаловаться на (явное) использование === в сравнении из-за его функциональной разницы. Но, к тому же, если вы явно используете логические success флаги, то я не думаю, что кто-то должен жаловаться на короткий стиль.

(Что касается вашего первого предложения, я не думаю, что было бы плохо явно явно проверять логическое значение true в динамически типизированном языке, если это значение действительно то, что вы хотите. Это излишне, когда статическая типизация уже ограничивает переменную быть логическим.)

7 голосов
/ 19 января 2011

Как правило, вы ожидаете логических имен переменных, таких как:

success, enabled, pass

чтобы иметь истинное значение. Итак

if(success) //or

if(enabled) //or

if(pass) //or

if(enabled) //or

понятно и логически читабельно. Но если у вас есть переменные, такие как:

result, status, port1.bit7

лучше написать:

if(result == true) //or

if(status == false) //or

if(port1.bit7 == true)

потому что это легко понять таким образом, как пример ниже:

if(result)
{
  ....
}

Удобочитаемость - это ремонтопригодность.

2 голосов
/ 19 января 2011

Что может пойти не так? Точно, ничего. В лучшем случае ваша функция ничего не делает. Это еще лучше, чем принять случайный аргумент как true.

Если вы используете true все остальное время, вам также следует явно проверить его.

Хотя я уверен в пользу if foo: в Python, здесь есть большая разница, и в том-то и дело, что в конечном итоге какой-то случайный программист jQuery может долго ждать и думает: «О! строка и new Boolean() "и использует это.

Что касается предложения Шона использовать !!, это действительно зависит от того, хотите ли вы, чтобы логическое значение было принято, или что-то, что было бы правдой. Для чистого API я бы принял только логические значения.

1 голос
/ 25 августа 2017

Чтобы добавить к этому диалогу, переменные sessionStorage и localStorage могут храниться только как строки сегодня, поэтому, если вы используете:

sessionStorage.setItem('completed',true);

Фактически он будет преобразован в строку и сохранен как 'true'. Я видел много людей, пишущих методы и преобразования для манипулирования этим значением, чтобы они могли использовать оператор if, используя логическое значение, где простое

if sessionStorage.getItem('completed') === 'true';

было бы достаточно, и, на мой взгляд, он легко читается и поддерживается.

1 голос
/ 19 января 2011

Я много читал о JavaScript, и никогда не видел, чтобы кто-то говорил, что if(success) - плохая практика.Я бы сделал это.Вы уверены, что параметр success всегда будет логическим?Прямо сейчас, если это когда-нибудь изменится на что-то другое, вам придется отредактировать функцию.Но если вы просто используете if(success), он будет работать для других значений "истинно" и "неправильно", например, строка против пустой строки, или 1 против 0.

Если вы хотите преобразовать все, чтоПараметр соответствует его логическому значению, вы можете просто дважды отрицать его: !!success;но в условных выражениях это не обязательно.

0 голосов
/ 12 декабря 2013

Это запах кода или языка, или детали реализации, или соглашение?

Действительно, это зависит от ситуации.

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

В том же духе Хоар извинился за изобретение ссылки null, которая настолько близка к корню этой правдивой проблемы, насколько я вижу. Дизайн JavaScript только запутывает проблему, добавляя еще больше правдивых значений, заставляя многих просто выступать за явную проверку, чтобы избежать трудного отслеживания ошибок (Дуглас Крокфорд). Сообщество JavaScript приняло сам язык, немного застряло. Основная команда Python выступает за обратное, так как языковой дизайн, похоже, настроен на упрощение вещей, а не на их смешение, и основная команда все еще планирует изменения в языке. Небольшие итеративные изменения - это сущность значительных улучшений со временем, будь то соглашение или языковой дизайн.

Оба являются хорошими стратегиями для их конкретной ситуации. Я не говорю, что это исключительный источник улучшений, но это основной источник улучшений в настоящее время.

Например, True и False на самом деле являются подклассами int в Python, в частности 0 и 1. Это имеет несколько конструктивных преимуществ. Тогда сторонники PEP8 предпочитают делать

if a_reference:
    pass

Единственный момент, когда None действительно нужно использовать в Python, - это указание необязательного параметра.

def foo(bar=optional): # NOTE I made up this idealistic construct
    """Looks good at the surface"""
    pass

def foo(bar=None):
    """But this is clear to the programmer"""
    pass

JavaScript неявно имеет все переменные как необязательные:

function foo(x, y, z) {
    // Certainly not clear to the programmer.
}

И Крокфорд выступает за явную проверку вещей, чтобы попытаться внести некоторую ясность в язык.

if (foo === undefined) {
    // pass
}

В основном JavaScript добавил нулевую ссылку # 2, известную как undefined. Я также думаю, что это забавно, что язык JavaScript так плохо рассматривается сообществом программистов, что они считают справедливым компромисс добавить сложность использования чего-то вроде CoffeeScript, GWT, Pyjamas, просто чтобы иметь лучший клиентский язык. Конечно, я не согласен с дополнительной сложностью, но, к сожалению, некоторые люди могут получить выгоду, хотя бы временно, и быстрее справиться с задачей, а не работать с JavaScript.

Я думаю, что в конечном итоге это глупое решение.

...