Как я могу преобразовать строку в логическое значение в JavaScript?

2557

Могу ли я преобразовать строку, представляющую логическое значение (например, 'true', 'false') во внутренний тип в JavaScript?

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

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

var myValue = document.myForm.IS_TRUE.value;
var isTrueSet = myValue == 'true';

Есть ли лучший способ сделать это?

Kevin
источник
50
"Есть ли лучший способ сделать это?" - есть конечно худший путь: Dstring=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse);
Марк К Коуэн
3
Легко обрабатывать строки и bools:function parseBool(val) { return val === true || val === "true" }
WickyNilliams
1
@Markfunction checkBool(x) { if(x) {return true;} else {return false;} }
Себи
2
@Sebi: Вы забыли задокументировать это:if (checkBool(x) != false) { ... } else { ... }
Марк К Коуэн
3
!!(parseInt(value) || value === "true")
Эндрю Лука

Ответы:

3484

Делать:

var isTrueSet = (myValue == 'true');

Вы можете сделать его более строгим, используя оператор идентификации ( ===), который не делает никаких неявных преобразований типов, когда сравниваемые переменные имеют разные типы, вместо оператора равенства ( ==).

var isTrueSet = (myValue === 'true');

Не рекомендуется:

Вы, вероятно, должны быть осторожны при использовании этих двух методов для ваших конкретных потребностей:

var myBool = Boolean("false");  // == true

var myBool = !!"false";  // == true

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

гинапс
источник
196
myValue === 'true';точно эквивалентно myValue == 'true';. Там нет никакой выгоды в использовании ===более чем ==здесь.
Тим Даун
551
Я следую совету и использованию Крокфорда=== и !==всякий раз, когда это имеет смысл, что почти всегда.
Гинапс
55
Как насчет «ИСТИНА» в верхнем регистре, например?
BMiner
102
@guinaps Я обычно следую советам Крокфорда, но сценарий « ==против» ===- один из немногих, в которых я не участвую . Я совершенно не согласен с тем, что его «почти всегда» имеет смысл использовать ===. Существуют слабо типизированные языки, потому что мы не хотим заботиться о типе; если мы проверяем что-то вроде этого, if (price >= 50)нам все равно, начинается ли оно как строка. Я говорю, что в большинстве случаев мы хотим , чтобы типы были подтасованы. В тех редких случаях, когда мы не хотим жонглировать типами (например if (price === null)), мы используем ===. Это то, что я делал годами, и у меня никогда не было проблем.
JMTyler
169
@JMTyler может пропустить программиста по техническому обслуживанию, который придет после. Всегда используйте правильный оператор сравнения! Если вы «точно» знаете типы с обеих сторон, но не используете ===, у меня не будет этих знаний при рассмотрении вашего кода позже. Если ваш код используется повторно, это может стать кошмаром. Если вы ДЕЙСТВИТЕЛЬНО хотите, чтобы ваши типы «жонглировали», как вы говорите, тогда используйте «==», но слишком много разработчиков JS сработают слишком легко, лучше уж сжать ваш код. Как часто я хочу, чтобы строка «ложь» означала логическое «истина»?
aikeru
687

Предупреждение

Этот устаревший ответ с большим количеством голосов является технически правильным, но он охватывает только очень специфический сценарий, когда ваше строковое значение ТОЧНО "true"или "false".

Недопустимая строка json, переданная в эти функции ниже, БУДЕТ генерировать исключение .


Оригинальный ответ:

Как насчет?

JSON.parse("True".toLowerCase());

или с помощью jQuery

$.parseJSON("TRUE".toLowerCase());
Люк
источник
62
Проблема в том, что многие потенциальные значения генерируют ошибку разбора, которая останавливает выполнение JS. Итак, запуск JSON.parse («ЛОЖЬ») бомбит Javascript. Суть вопроса, я думаю, состоит не в том, чтобы просто решить эти точные случаи, а в том, чтобы быть устойчивым к другим случаям.
BishopZ
3
@ Лук, это решение на самом деле именно то, что мне нужно; хорошо, оборачивая это в попытку ... поймать все же. Я хотел преобразовать в bool, только если это было логическое значение в строке; в противном случае просто используйте предоставленную строку. Это работает! Спасибо.
Джедмао
47
Это довольно просто сказать, JSON.parse("TRUE".toLowerCase())чтобы он мог правильно разобрать.
Ага
27
почему так много голосов? Это неэффективно и ужасно. Что дальше? 'true'.length === 4?
Максим Ви.
21
@MaksimVi. typeof str==="string"&& str.length===4&& str.charAt(0)==="t" && str.charAt(1)==="r" && str.charAt(2)==="u" && str.charAt(3)==="e"&& true===true && true!==false && false===false// просто чтобы быть уверенным
Vitim.us
223
stringToBoolean: function(string){
    switch(string.toLowerCase().trim()){
        case "true": case "yes": case "1": return true;
        case "false": case "no": case "0": case null: return false;
        default: return Boolean(string);
    }
}
Стивен
источник
43
На самом деле это можно упростить. 1) Нет необходимости проверять "true", "yes"а "1". 2) toLowerCaseне возвращается null. 3) так Boolean(string)же, как string!==""здесь. =>switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;}
Роберт
15
@ Роберт, хороший, но я бы предпочел использовать по умолчанию false.
Drigoangelo
@drigoangelo Наличие default: return true;конечно возможно. Но это изменило бы поведение функции.
Роберт
2
Я подумал, что это лучший ответ, и хотел уточнить его здесь: stackoverflow.com/questions/263965/…
BrDaHa
9
если вы нормализуете данные, вызывая .toLowerCase (), то вы, возможно, захотите добавить в trim (), чтобы также удалить пробелы
jCuga
174

Я думаю, что это очень универсально:

if (String(a) == "true") ...

Идет:

String(true) == "true"     //returns true
String(false) == "true"    //returns false
String("true") == "true"   //returns true
String("false") == "true"  //returns false
ANDER
источник
20
Когда вы можете получить строку в верхнем регистре или логическое значение, тоString(a).toLowerCase() === 'true'
pauloya
String("what about input like this that isn't a bool?") == "true"
Томас Эдинг
6
@ThomasEding false ... что вы хотите, чтобы он вернулся?
Snowburnt
2
можно даже сократить, не используя String()конструктор:true+'' === 'true' // true
Тодд
1
КСТАТИ, для 1 или 0 он также должен бросить на ложь или истину
Мигель
128

Не забудьте сопоставить регистр:

var isTrueSet = (myValue.toLowerCase() === 'true');

Кроме того, если это флажок элемента формы, вы также можете определить, установлен ли флажок:

var isTrueSet = document.myForm.IS_TRUE.checked;

Предполагая, что, если это проверено, это "установлено" равным true. Это оценивается как истина / ложь.

Джаред Фарриш
источник
3
Это вызовет исключение, если это myValueпроизойдет null, trueили какой-то другой тип ...
mik01aj
116

Вы можете использовать регулярные выражения:

/*
 * Converts a string to a bool.
 *
 * This conversion will:
 *
 *  - match 'true', 'on', or '1' as true.
 *  - ignore all white-space padding
 *  - ignore capitalization (case).
 *
 * '  tRue  ','ON', and '1   ' will all evaluate as true.
 *
 */
function strToBool(s)
{
    // will match one and only one of the string 'true','1', or 'on' rerardless
    // of capitalization and regardless off surrounding white-space.
    //
    regex=/^\s*(true|1|on)\s*$/i

    return regex.test(s);
}

Если вам нравится расширять класс String, вы можете сделать:

String.prototype.bool = function() {
    return strToBool(this);
};

alert("true".bool());

Для тех (см. Комментарии), которые хотели бы расширить объект String, чтобы получить это, но беспокоятся о перечисляемости и беспокоятся о конфликте с другим кодом, который расширяет объект String:

Object.defineProperty(String.prototype, "com_example_bool", {
    get : function() {
        return (/^(true|1)$/i).test(this);
    }
});
alert("true".com_example_bool);

(Конечно, не будет работать в старых браузерах, и Firefox показывает false, в то время как Opera, Chrome, Safari и IE показывают true. Ошибка 720760 )

shrewmouse
источник
10
Вы всегда можете добавить префикс функции, если вы боитесь, что она помешает другому коду. Если какой-то код все еще ломается, этот код слишком хрупок и должен быть исправлен. Если ваша добавленная функция делает объект слишком тяжелым, если это вызывает проблемы с производительностью для другого кода, тогда, очевидно, вы не хотите этого делать. Но я не думаю, что вообще плохая идея расширять встроенные объекты. Они также не были бы общедоступными, если бы это было так.
Shadow2531
41
@DTrejo @Szymon Я не согласен. Это именно та вещь, для которой перегружен прототип. Если вы боитесь, что он нарушит (плохой) код, на который опирается for..in, есть способы скрыть свойства от перечисления. См Object.defineProperty.
devios1
Чтобы следовать соглашению, я бы назвал этоparseBool
Гузарт
8
Булев синтаксический разбор не относится к классу String. В результате вы получите любое количество парсеров и конверсий мусора. -1 к смене прототипов вообще. -1 к решениям, которые не работают кросс-браузер. -1 за плохой дизайн.
Томас В.
1
Вот сравнение производительности всех ответов. stackoverflow.com/a/28588344/2824333
Соспедра
50

Вуд-глаз, будь осторожен. Увидев последствия после применения верхнего ответа с 500+ ответами, я чувствую себя обязанным опубликовать что-то действительно полезное:

Начнем с самого короткого, но очень строгого способа:

var str = "true";
var mybool = JSON.parse(str);

И покончим с правильным, более терпимым способом:

var parseBool = function(str) 
{
    // console.log(typeof str);
    // strict: JSON.parse(str)

    if(str == null)
        return false;

    if (typeof str === 'boolean')
    {
        return (str === true);
    } 

    if(typeof str === 'string')
    {
        if(str == "")
            return false;

        str = str.replace(/^\s+|\s+$/g, '');
        if(str.toLowerCase() == 'true' || str.toLowerCase() == 'yes')
            return true;

        str = str.replace(/,/g, '.');
        str = str.replace(/^\s*\-\s*/g, '-');
    }

    // var isNum = string.match(/^[0-9]+$/) != null;
    // var isNum = /^\d+$/.test(str);
    if(!isNaN(str))
        return (parseFloat(str) != 0);

    return false;
}

Тестирование:

var array_1 = new Array(true, 1, "1",-1, "-1", " - 1", "true", "TrUe", "  true  ", "  TrUe", 1/0, "1.5", "1,5", 1.5, 5, -3, -0.1, 0.1, " - 0.1", Infinity, "Infinity", -Infinity, "-Infinity"," - Infinity", " yEs");

var array_2 = new Array(null, "", false, "false", "   false   ", " f alse", "FaLsE", 0, "00", "1/0", 0.0, "0.0", "0,0", "100a", "1 00", " 0 ", 0.0, "0.0", -0.0, "-0.0", " -1a ", "abc");


for(var i =0; i < array_1.length;++i){ console.log("array_1["+i+"] ("+array_1[i]+"): " + parseBool(array_1[i]));}

for(var i =0; i < array_2.length;++i){ console.log("array_2["+i+"] ("+array_2[i]+"): " + parseBool(array_2[i]));}

for(var i =0; i < array_1.length;++i){ console.log(parseBool(array_1[i]));}
for(var i =0; i < array_2.length;++i){ console.log(parseBool(array_2[i]));}
Стефан Штайгер
источник
Просто помните, что старым браузерам может потребоваться полифил JSON, если вы используете первый метод.
DRaehal
1
Как быстро преобразовать "ложную" строку в falseлогическое значение с помощью JSON.parse? С точки зрения процессора, производительности памяти
Green
Разве не было бы проще начать с if (str) {...}, чтобы устранить все, что уже является ложным? И в этом условии if нужно просто беспокоиться о возвращении true, потому что вы уже заканчиваете возвратом false!
Larphoid
Помните, что вы можете сократить многие строковые тесты до (["true", "yes", "1"]. IndexOf (str.toLowerCase (). Trim ())! = -1) и использовать запасной вариант Boolean (str), чтобы охватить такие вещи, как «
Скотт
38

Я думал, что ответ @Steven был лучшим и позаботился о гораздо большем количестве случаев, чем если бы входящее значение было просто строкой. Я хотел бы немного его расширить и предложить следующее:

function isTrue(value){
    if (typeof(value) === 'string'){
        value = value.trim().toLowerCase();
    }
    switch(value){
        case true:
        case "true":
        case 1:
        case "1":
        case "on":
        case "yes":
            return true;
        default: 
            return false;
    }
}

Нет необходимости покрывать все falseслучаи, если вы уже знаете все trueслучаи, которые вам придется учитывать. Вы можете передать в этот метод что угодно, что может передать trueзначение (или добавить другие, это довольно просто), и все остальное будет рассмотреноfalse

BrDaHa
источник
Я использую этот, поскольку он охватывает вещи, которые вы получаете из атрибутов XML / HTML ElementNodes, таких какautocomplete="on"
philk
2
Я бы добавил .trim () перед toLowerCase ()
Луис Лобо
34

Универсальное решение с анализом JSON:

function getBool(val) {
    return !!JSON.parse(String(val).toLowerCase());
}

getBool("1"); //true
getBool("0"); //false
getBool("true"); //true
getBool("false"); //false
getBool("TRUE"); //true
getBool("FALSE"); //false

ОБНОВЛЕНИЕ (без JSON):

function getBool(val){ 
    var num = +val;
    return !isNaN(num) ? !!num : !!String(val).toLowerCase().replace(!!0,'');
}

Я также создал скрипку, чтобы проверить ее http://jsfiddle.net/remunda/2GRhG/

Ян Ремунда
источник
1
Версия без JSON имеет некоторые недостатки: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). replace (!! 0, ''))); производит правда
Этьен
3
getBool(undefined)произойдет сбой при использовании исходной версии JSON и вернет true для 2-й версии. Вот третья версия, которая возвращает false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). replace (!! 0, '')); }
Рон Мартинес
31

Ваше решение в порядке.

Использование ===в этом случае будет просто глупым, так как поле valueвсегда будет a String.

Джонни Бьюкенен
источник
17
Почему вы думаете, что было бы глупо использовать ===? С точки зрения производительности было бы точно так же, если оба типа являются строками. Во всяком случае, я скорее использую, ===так как я всегда избегаю использования ==и !=. Обоснования: stackoverflow.com/questions/359494/…
Мариано Дезанце
3
Так как valueвсегда будет stringни ==ни ===глупо. Оба являются подходящим инструментом для этой работы. Они отличаются только тогда, когда типы не равны. В этом случае ===просто возвращает falsewhile, ==выполняя сложный алгоритм приведения типа перед сравнением.
Роберт
23
var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) { 
    return !falsy.test(val) && !!val;
};

Это возвращает falseдля каждого falsy значения и trueдля каждого значения truthy за исключением 'false', 'f', 'no', 'n', и '0'(без учета регистра).

// False
Boolean.parse(false);
Boolean.parse('false');
Boolean.parse('False');
Boolean.parse('FALSE');
Boolean.parse('f');
Boolean.parse('F');
Boolean.parse('no');
Boolean.parse('No');
Boolean.parse('NO');
Boolean.parse('n');
Boolean.parse('N');
Boolean.parse('0');
Boolean.parse('');
Boolean.parse(0);
Boolean.parse(null);
Boolean.parse(undefined);
Boolean.parse(NaN);
Boolean.parse();

//True
Boolean.parse(true);
Boolean.parse('true');
Boolean.parse('True');
Boolean.parse('t');
Boolean.parse('yes');
Boolean.parse('YES');
Boolean.parse('y');
Boolean.parse('1');
Boolean.parse('foo');
Boolean.parse({});
Boolean.parse(1);
Boolean.parse(-1);
Boolean.parse(new Date());
Prestaul
источник
20

У логического объекта нет метода parse. Boolean('false')возвращает true, так что это не сработает. !!'false'также возвращается true, так что это тоже не сработает.

Если вы хотите, чтобы строка 'true'возвращала логическое значение, trueа строка 'false'возвращала логическое значение false, то самое простое решение - использовать eval(). eval('true')возвращает true и eval('false')возвращает false. Имейте в виду последствия для производительности при использовании, eval()хотя.

10basetom
источник
Чтобы понять, что является «неправильным» (или правильным) в eval, ознакомьтесь со статьями, такими как javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval или выполните поиск в
стеке потока
2
Я согласен, что var isTrueSet = (myValue === 'true');это лучший ответ.
thdoan
Мне нравится, что это лаконично. Но это не удается эффектно для основного случая eval('TRUE'); доказывая еще раз, это eval()зло.
Снеговик
@Area 51 «Детективная беллетристика» тем же способом, что и JSON.parse('TRUE')из приведенного ниже ответа, также не дает впечатляющих результатов. Довольно просто вызвать условие ошибки в JavaScript (или любом другом языке). Чтобы учесть это, вы должны сначала нормализовать строку, например,var myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
thdoan
1
@ 10basetom: Совершенно верно. Вы должны включить .toLowerCase()в ответ мою точку зрения. Я не пытаюсь ничего форсировать. Прописные буквы TRUE- это достаточно распространенное значение, которое возвращают многие виджеты пользовательского интерфейса.
Снеговик
18

Это было взято из принятого ответа, но на самом деле у него есть очень слабое место, и я шокирован тем, как он получил это количество голосов, проблема с этим, что вы должны рассмотреть случай строки, потому что это чувствительно к регистру

var isTrueSet = (myValue.toLowerCase() === 'true');
оборота Хакам Фосток
источник
16

Я использую следующее:

function parseBool(b) {
    return !(/^(false|0)$/i).test(b) && !!b;
}

Эта функция выполняет обычное логическое приведение, за исключением строк «false» (без учета регистра) и «0».

zobier
источник
16

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

Краткое изложение результатов (чем выше, тем лучше):

  1. Условное заявление : 2 826 922
  2. Корпус переключателя на объекте Bool : 2 825 469
  3. Кастинг в JSON : 1 867 774
  4. !! конверсии : 805,322
  5. Прототип строки : 713 637

Они связаны с соответствующим ответом, где вы можете найти больше информации (плюсы и минусы) о каждом; особенно в комментариях.

оборота соспедра
источник
"что-то пошло не так" при попытке просмотреть тест
jsPerf
13
Boolean.parse = function (str) {
  switch (str.toLowerCase ()) {
    case "true":
      return true;
    case "false":
      return false;
    default:
      throw new Error ("Boolean.parse: Cannot convert string to boolean.");
  }
};
Томас Эдинг
источник
2
Вы можете использовать true.toString () вместо «true», чтобы быть еще более чистым :-)
до
Не меняйте глобальные переменные, старайтесь держать свои изменения изолированными, возможно, function parseBooleanвместо этого создайте новое
Steel Brain
13

Выражение, которое вы ищете, просто

/^true$/i.test(myValue)

как в

var isTrueSet = /^true$/i.test(myValue);

Это проверяет myValueрегулярное выражение без учета регистра и не изменяет прототип.

Примеры:

/^true$/i.test("true"); // true
/^true$/i.test("TRUE"); // true
/^true$/i.test("tRuE"); // true
/^true$/i.test(" tRuE"); // false (notice the space at the beginning)
/^true$/i.test("untrue"); // false (some other solutions here will incorrectly return true
/^true$/i.test("false");// returns false
/^true$/i.test("xyz");  // returns false
AndreasPizsa
источник
12

Чтобы преобразовать как строку («истина», «ложь»), так и логическое значение в логическое значение

('' + flag) === "true"

Где flagможно

 var flag = true
 var flag = "true"
 var flag = false
 var flag = "false"
Физер Хан
источник
12

Уже есть так много доступных ответов. Но в некоторых случаях может быть полезно следующее.

// One can specify all values against which you consider truthy
var TRUTHY_VALUES = [true, 'true', 1];

function getBoolean(a) {
    return TRUTHY_VALUES.some(function(t) {
        return t === a;
    });
}

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

getBoolean('aa'); // false
getBoolean(false); //false
getBoolean('false'); //false

getBoolean('true'); // true
getBoolean(true); // true
getBoolean(1); // true
Сандип Нирмал
источник
10

почему бы тебе не попробовать что-то подобное

Boolean(JSON.parse((yourString.toString()).toLowerCase()));

Он вернет ошибку, когда задан какой-то другой текст, а не истина или ложь, независимо от регистра, и будет также записывать числа в виде

// 0-> false
// any other number -> true
Йоан
источник
10

Эта функция может обрабатывать как строки, так и логические значения true / false.

function stringToBoolean(val){
    var a = {
        'true':true,
        'false':false
    };
    return a[val];
}

Демонстрация ниже:

function stringToBoolean(val) {
  var a = {
    'true': true,
    'false': false
  };
  return a[val];
}

console.log(stringToBoolean("true"));

console.log(typeof(stringToBoolean("true")));

console.log(stringToBoolean("false"));

console.log(typeof(stringToBoolean("false")));

console.log(stringToBoolean(true));

console.log(typeof(stringToBoolean(true)));

console.log(stringToBoolean(false));

console.log(typeof(stringToBoolean(false)));

console.log("=============================================");
// what if value was undefined? 
console.log("undefined result:  " + stringToBoolean(undefined));
console.log("type of undefined result:  " + typeof(stringToBoolean(undefined)));
console.log("=============================================");
// what if value was an unrelated string?
console.log("unrelated string result:  " + stringToBoolean("hello world"));
console.log("type of unrelated string result:  " + typeof(stringToBoolean(undefined)));

user1063287
источник
9

Я использую этот

String.prototype.maybeBool = function(){

    if ( ["yes", "true", "1", "on"].indexOf( this.toLowerCase() ) !== -1 ) return true;
    if ( ["no", "false", "0", "off"].indexOf( this.toLowerCase() ) !== -1 ) return false;

    return this;

}

"on".maybeBool(); //returns true;
"off".maybeBool(); //returns false;
"I like js".maybeBool(); //returns "I like js"
Adam Pietrasiak
источник
Это хорошо, но работает только со строковым типом. Представьте, что это нужно использовать переменной, которая может быть "true"или true. Если придет второй, это не будет работать. Можно ли document.prototypeиспользовать это, где мы хотим?
MarceloBarbosa
Это выглядит элегантно. Отличная работа! Однако я заметил, что перегрузка базовых прототипов в больших JS-приложениях (которые также требуют модульного тестирования) может привести к некоторому неожиданному поведению (а именно, когда вы захотите выполнить итерацию с помощью for для массива с перегруженным прототипом, вы получите некоторые свойства, которые вы обычно не ожидаете). Вы были предупреждены. ;)
cassi.lup
ваш вариант, который принимает также логическую функцию StringOrElse2Bool (sob) {if (typeof sob === "string") {return ["no", "false", "0", "off"]. indexOf (sob.toLowerCase ())! == -1? ложь Правда; } else {return !!
sob

8

Руки вниз самым простым способом (при условии, что ваша строка будет 'true' или 'false') это:

var z = 'true';
var y = 'false';
var b = (z === 'true'); // will evaluate to true
var c = (y === 'true'); // will evaluate to false

Всегда используйте оператор === вместо оператора == для этих типов преобразований!


4
О каком обращении вы говорили? :-)
YMMD

1
При сравнении строк в JavaScript нет разницы между использованием операторов == или ===, когда не используются преобразования. Здесь вы сравниваете со строками, поэтому нет преобразования типов. См stackoverflow.com/questions/359494/...
ars265

8

Как сказал @ Shadow2531, вы не можете просто конвертировать его напрямую. Я бы также предложил, чтобы вы рассматривали строковые входы помимо «true» и «false», которые являются «truey» и «falsey», если ваш код будет повторно использоваться / использоваться другими. Это то, что я использую:

function parseBoolean(string) {
  switch (String(string).toLowerCase()) {
    case "true":
    case "1":
    case "yes":
    case "y":
      return true;
    case "false":
    case "0":
    case "no":
    case "n":
      return false;
    default:
      //you could throw an error, but 'undefined' seems a more logical reply
      return undefined;
  }
}

7

Вы должны отделить (в вашем мышлении) значение вашего выбора и представление этого значения.

Укажите точку в логике JavaScript, где им нужно перейти от строковых сторожей к нативному типу, и проведите там сравнение, предпочтительно там, где это делается только один раз для каждого значения, которое необходимо преобразовать. Не забудьте указать, что должно произойти, если строка sentinel не та, которую знает сценарий (т. Е. Используется ли по умолчанию значение true или false?)

Другими словами, да, вам нужно зависеть от значения строки. :-)


7

Мой взгляд на этот вопрос заключается в том, что он направлен на достижение трех целей:

  • Вернуть true / false для значений truey и falsey, но также вернуть true / false для нескольких строковых значений, которые были бы true или false, если бы они были булевыми, а не строковыми.
  • Во-вторых, предоставьте упругий интерфейс, чтобы значения, отличные от указанных, не сработали, а вернули значение по умолчанию
  • В-третьих, делайте все это, используя как можно меньше кода.

Проблема с использованием JSON заключается в том, что он не работает, вызывая ошибку Javascript. Это решение не является устойчивым (хотя оно удовлетворяет 1 и 3):

JSON.parse("FALSE") // fails

Это решение не является достаточно кратким:

if(value === "TRUE" || value === "yes" || ...) { return true; }

Я работаю над решением этой проблемы для Typecast.js . И лучшее решение для всех трех целей это:

return /^true$/i.test(v);

Он работает во многих случаях, не дает сбоя при передаче значений типа {} и очень лаконичен. Кроме того, он возвращает значение false в качестве значения по умолчанию, а не неопределенного значения или выдачи ошибки, что более полезно при разработке свободно написанного Javascript. Браво на другие ответы, которые предложили это!

BishopZ
Просто чтобы вернуться к вашим целям, единственная проблема с вашим третьим и лучшим решением состоит в том, что оно не соответствует Цели # 1 - оно вернет true только для значения 'true' , но не для любого достоверного ввода. Для того, чтобы оно соответствовало Задаче № 1, оно лишь немного более кратко, чем Решение № 2, и гораздо менее читабельно.
JMTyler
return /^(true|yes|1|t|y)$/i.test(str);
Кевин Баучер
7

Я немного поздно, но у меня есть небольшой отрывок , чтобы сделать это, по существу , поддерживает все JScripts truthey / falsey / нечисто -ness , но включает в себя "false"как acceptible значение для ложных.

Я предпочитаю этот метод упомянутым, потому что он не полагается на стороннюю программу для анализа кода (то есть: eval / JSON.parse), что, на мой взгляд, является излишним, он достаточно короткий, чтобы не требовать служебной функции, и поддерживает другие соглашения truthey / falsey.

var value = "false";
var result = (value == "false") != Boolean(value);

// value = "true"  => result = true
// value = "false" => result = false
// value = true    => result = true
// value = false   => result = false
// value = null    => result = false
// value = []      => result = true
// etc..
Dead.Rabit
источник
7

другое решение. jsFiddle

var toBoolean = function(value) {
    var strValue = String(value).toLowerCase();
    strValue = ((!isNaN(strValue) && strValue !== '0') &&
        strValue !== '' &&
        strValue !== 'null' &&
        strValue !== 'undefined') ? '1' : strValue;
    return strValue === 'true' || strValue === '1' ? true : false
};

тесты запускаются в узле

> toBoolean(true)
true
> toBoolean(false)
false
> toBoolean(undefined)
false
> toBoolean(null)
false
> toBoolean('true')
true
> toBoolean('True')
true
> toBoolean('False')
false
> toBoolean('false')
false
> toBoolean('0')
false
> toBoolean('1')
true
> toBoolean('100')
true
> 
Вбранден
источник
7

Боже мой, некоторые из этих ответов просто дикие. Я люблю JS и его бесконечное количество способов снять шкуру.

Мое предпочтение, которое я был потрясен, чтобы не видеть, уже:

testVar = testVar.toString().match(/^(true|[1-9][0-9]*|[0-9]*[1-9]+|yes)$/i) ? true : false;
ОкаБака
источник
6

Один лайнер

Нам просто нужно учитывать "ложную" строку, поскольку любая другая строка (включая "истину") уже есть true.

function b(v){ return v==="false" ? false : !!v; }

Тестовое задание

b(true)    //true
b('true')  //true
b(false)   //false
b('false') //false

Более исчерпывающая версия

function bool(v){ return v==="false" || v==="null" || v==="NaN" || v==="undefined" || v==="0" ? false : !!v; }

Тестовое задание

bool(true)        //true
bool("true")      //true
bool(1)           //true
bool("1")         //true
bool("hello")     //true

bool(false)       //false
bool("false")     //false
bool(0)           //false
bool("0")         //false
bool(null)        //false
bool("null")      //false
bool(NaN)         //false
bool("NaN")       //false
bool(undefined)   //false
bool("undefined") //false
bool("")          //false

bool([])          //true
bool({})          //true
bool(alert)       //true
bool(window)      //true
Vitim.us
источник