题 如何在JavaScript中将字符串转换为布尔值?


我可以将表示布尔值的字符串(例如,'true','false')转换为JavaScript中的内部类型吗?

我有一个隐藏的HTML格式,根据用户在列表中的选择进行更新。此表单包含一些表示布尔值的字段,并使用内部布尔值进行动态填充。但是,一旦将此值放入隐藏的输入字段,它就会变成一个字符串。

我可以找到确定字段的布尔值的唯一方法,一旦将其转换为字符串,就要依赖于字符串表示的字面值。

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

有没有更好的方法来实现这一目标?


1840
2017-11-05 00:13


起源


只是为了突出一个避免三重等于比较的奇怪例子:我有一个功能 currentSortDirection() 返回 1 升序排序, 0 对于降序排序,和 -1 没有设定。运用 while (currentSortDirection() != desiredSortDirection) { sortColumn() } 从那以后工作得很好 -1 != true  和  -1 != false......但是改成这个 while (Boolean(currentSortDirection) !== ...) {...} 军队 -1 变成一个 true,需要额外几行准备,只是为了让jshint高兴。 - Droogans
“有没有更好的方法来实现这一目标?” - 当然有一种更糟糕的方式:D string=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse); - Mark K Cowan
轻松处理字符串和bool: function parseBool(val) { return val === true || val === "true" } - WickyNilliams
@标记 function checkBool(x) { if(x) {return true;} else {return false;} } - Sebi
@Sebi:你忘了记录它: if (checkBool(x) != false) { ... } else { ... } - Mark K Cowan


答案:


做:

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

您可以通过使用身份运算符使其更严格(===),当比较变量具有不同类型而不是相等运算符时,它不会进行任何隐式类型转换(==)。

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

别:

你可能应该 使用这两种方法时要小心 满足您的特定需求:

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

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

任何不是空字符串的字符串都将计算为 true 通过使用它们。虽然它们是我能想到的关于布尔转换的最干净的方法,但我认为它们不是你想要的。


2473



myValue === 'true'; 恰恰相当于 myValue == 'true';。使用没有任何好处 === 过度 == 这里。 - Tim Down
我跟随 克罗克福德的建议 并使用 === 和 !== 只要它有意义,这几乎总是如此。 - guinaps
例如,大写的“TRUE”怎么样? - BMiner
@guinaps我通常遵循Crockford的建议,但是 == 与 === 情景是我不知道的少数情景之一。一世 全然 不同意它“几乎总是”使用有意义 ===。松散类型的语言 存在 因为我们不想关心这种类型;如果我们检查类似的东西 if (price >= 50) 我们不在乎它是否以字符串开头。我说, 最 当时,我们 想 要变成的类型。在极少数情况下,我们不希望类型杂耍(例如 if (price === null)),然后我们使用 ===。这就是我多年来一直在做的事情 决不 有一个问题。 - JMTyler
@JMTyler可能会忽略维护程序员。始终使用正确的比较运算符!如果您确实“确定”双方的类型,但不使用===,那么在以后查看您的代码时我将不会有这些知识。如果您的代码被重用,这可能会成为一场噩梦。如果你真的想要你的类型'玩杂耍',那么使用'==',但太多的JS开发人员会在这方面绊倒,更好地收紧你的代码。我多久需要字符串'false'来表示布尔值'true'? - aikeru


警告

这个高度支持的遗留答案在技术上是正确的,但只涵盖非常具体的情况,当您的字符串值完全正确时 "true" 要么 "false" (必须小写)。

传递给下面这些函数的无效json字符串 将抛出异常


原始答案:

怎么样?

JSON.parse("true");

或者使用jQuery

$.parseJSON("true");

518



这个问题是很多潜在的值会产生一个解析错误,导致JS执行停止。所以运行JSON.parse(“FALSE”)炸弹Javascript。我认为,问题的关键不在于简单地解决这些确切的案例,而是对其他案件具有弹性。 - BishopZ
说起来很简单 JSON.parse("TRUE".toLowerCase()) 这样它就可以正确解析。 - Yuck
@Ebenezar为什么我们关心ie7?它在全球市场占有率约为1%。 - Todd
@Ebenezar我可以尊重这一点,但我的时间花在优化其他> 99%。在15中使用ie7的人显然不太关心互联网的事情。干杯。 - Todd
为什么会有这么多的赞成?这是低效和可怕的。接下来是什么? 'true'.length === 4? - Maksim Vi.


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

186



实际上它可以简化。 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;} - Robert
@Robert,很好,但我宁愿默认为 false代替。 - drigoangelo
@drigoangelo有 default: return true; 肯定是可能的。但它会改变函数的行为。 - Robert
我认为这是最好的答案,并希望在此详细说明: stackoverflow.com/questions/263965/... - BrDaHa
如果你通过调用.toLowerCase()来规范化数据,那么你可能不想抛出trim()以去除空白 - jCuga


我认为这很普遍:

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

它会:

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

120



当你可以接收大写的字符串或布尔值时,那么 String(a).toLowerCase() === 'true' - pauloya
@PauloManuelSantos这个真的是这里最好的单行:)很棒! - Adam Lukaszczyk
String("what about input like this that isn't a bool?") == "true" - Thomas Eding
@ThomasEding false ...你想要它返回什么? - Snowburnt
甚至可以通过不使用 String() 构造函数: true+'' === 'true' // true - Todd


您可以使用正则表达式:

/*
 * 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显示错误,而Opera,Chrome,Safari和IE显示为真。 错误720760


105



修改内置对象的原型不是一个好主意! - DTrejo
如果您害怕它会干扰其他一些代码,您可以随时为该函数添加前缀。如果某些代码仍然中断,那么代码太脆弱了,应该修复。如果您添加的函数使对象太重而导致其他代码出现性能问题,那么,显然您不希望这样做。但是,我认为扩展内置对象通常不是一个坏主意。如果是这样的话,它们也不会公开扩展。 - Shadow2531
你不应该修改原型 - Szymon Wygnański
@DTrejo @Szymon我不同意。这正是重载原型的那种东西。如果你害怕破坏(差)代码依赖for..in,有一些方法可以隐藏枚举中的属性。看到 Object.defineProperty。 - devios1
布尔解析不属于String类..你最终会得到任何数量的垃圾解析器和转换。 -1一般改变原型。 -1到跨浏览器不起作用的解决方案。 -1表示设计不佳。 - Thomas W


记得要匹配案例:

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

此外,如果它是表单元素复选框,您还可以检测是否选中了复选框:

var isTrueSet = document.myForm.IS_TRUE.checked;

假设如果选中它,则“set”等于true。这评估为真/假。


103



你为什么要做三元?你已经有了一个布尔值 - nickf
因为你能?你在“那里已经有一个布尔”是什么意思? - Jared Farrish
Jared,===已经是一个布尔条件,三元是多余的。 - FlySwat
真正。反正我讨厌三元。好吧,我认为我在toLowerCase上是正确的,所以我编辑它以删除三元组。 - Jared Farrish
这将抛出异常,如果 myValue 碰巧是 null, true 或其他类型...... - mik01aj


木眼要小心。 在使用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]));}

39



请记住,如果您使用第一种方法,旧版浏览器可能需要JSON polyfill。 - DRaehal
将“假”字符串转换为多快 false 布尔值为 JSON.parse?在CPU,内存性能方面 - Green


你的解决方案很好。

运用 === 在这种情况下,就像场地一样,这只会是愚蠢的 value 将永远是一个 String


29



这是唯一明智的答案:) - Bobby Jack
为什么你认为使用它会很愚蠢 ===?就性能而言,如果两种类型都是字符串则完全相同。无论如何,我宁愿使用 === 因为我总是避免使用 == 和 !=。理由: stackoverflow.com/questions/359494/... - Mariano Desanze
以来 value 将永远是一个 string 也不 == 也不 === 很傻。两者都是这项工作的正确工具。它们只在类型不同时才有所不同 不 等于。在这种情况下 === 简单地回来 false 而 == 在比较之前执行复杂的类型强制算法。 - Robert


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


24



并非所有浏览器都支持JSON:/ - Aamir Afridi
好吧,我添加了功能,没有JSON :) - Jan Remunda
'without JSON'版本有一些缺陷:val =“0”; console.log(!!(+ val || String(val).toLowerCase()。replace(!! 0,'')));产生真实 - Etienne
好,谢谢。我把它修好并创造了小提琴 jsfiddle.net/remunda/2GRhG - Jan Remunda
getBool(undefined) 将崩溃使用原始JSON版本时将返回第二个版本的true。这是返回false的第3个版本:function getBool(val){var num; return val!= null &&(!isNaN(num = + val)?!! num:!! String(val).toLowerCase()。replace(!! 0,'')); } - Ron Martinez