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

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

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

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

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

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

30 ответов


Do:

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

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

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

нет:

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

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

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

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


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

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

недопустимая строка json, переданная в эти функции ниже исключение.


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

как насчет?

JSON.parse("true");

или с jQuery

$.parseJSON("true");

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);
    }
}

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

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

Он говорит:

String(true) == "true"     //returns true
String(false) == "true"    //returns false
String("true") == "true"   //returns true
String("false") == "true"  //returns false

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

/*
 * 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)


Не забудьте сопоставить случай:

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

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

var isTrueSet = document.myForm.IS_TRUE.checked;

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


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

начнем с самого короткого, но очень строгого пути:

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]));}

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

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


универсальное решение с JSON parse:

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/


Я думал, что ответ @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


var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) { 
    return !falsy.test(val) && !!val;
};

возвращает false для каждого ложного значения и true для каждого истинного значения, кроме '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());

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

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


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

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

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


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.");
  }
};

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

краткая информация о результатах (чем выше, тем лучше):

  1. условный оператор: 2,826,922
  2. переключить корпус на объект Bool: 2,825,469
  3. отливки В JSON: 1,867,774
  4. !! конверсии: 805,322
  5. прототип строку: 713,637

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


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

/^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

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

// 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

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

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

руки вниз самый простой способ (предполагая, что строка будет "true" или "false"):

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

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


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

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;
  }
}

чтобы преобразовать обе строки ("true"," false") и boolean в boolean

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

здесь flag может быть

 var flag = true
 var flag = "true"
 var flag = false
 var flag = "false"

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

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"

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

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

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

JSON.parse("FALSE") // fails

это решение недостаточно лаконично:

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

Я работаю над решением этой точной задачи для Typecast.js. И лучшим решением всех трех задач является следующее:--4-->

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

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


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

Я предпочитаю этот метод упомянутым, потому что он не полагается на третью сторону для анализа кода (i.e: 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..

другое решение. 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
> 

эта функция может обрабатывать строку, а также логическое значение 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)));

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

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

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


function parseBool(value) {
    if (typeof value === "boolean") return value;

    if (typeof value === "number") {
        return value === 1 ? true : value === 0 ? false : undefined;
    }

    if (typeof value != "string") return undefined;

    return value.toLowerCase() === 'true' ? true : false;
}

Я написал функцию, соответствующую filter_var PHP, которая делает это красиво. Доступно в gist:https://gist.github.com/CMCDragonkai/7389368

/**
 * Parses mixed type values into booleans. This is the same function as filter_var in PHP using boolean validation
 * @param  {Mixed}        value 
 * @param  {Boolean}      nullOnFailure = false
 * @return {Boolean|Null}
 */
var parseBooleanStyle = function(value, nullOnFailure = false){
    switch(value){
        case true:
        case 'true':
        case 1:
        case '1':
        case 'on':
        case 'yes':
            value = true;
            break;
        case false:
        case 'false':
        case 0:
        case '0':
        case 'off':
        case 'no':
            value = false;
            break;
        default:
            if(nullOnFailure){
                value = null;
            }else{
                value = false;
            }
            break;
    }
    return value;
};

String(true).toLowerCase() == 'true'; // true
String("true").toLowerCase() == 'true'; // true
String("True").toLowerCase() == 'true'; // true
String("TRUE").toLowerCase() == 'true'; // true

String(false).toLowerCase() == 'true'; // false

Если вы не уверены в вводе, вышеизложенное работает для boolean, а также для любой строки.