JavaScript检查字符串是否为真或假并转换为布尔值

19

有没有更好的方法来改进下面的语句,以检查val()是否为'true''false',如果是,则将其更改为布尔值。原因是,一些值可能是单词。

var thisval = $(this).val();
if (thisval == "true"){
    ao[id] = true;
} else if (thisval == "false"){
    ao[id] = false;
} else {
    ao[id] = $(this).val();
}

2
可能是重复的问题:如何在JavaScript中将字符串转换为布尔值? - KevSheedy
这段代码有什么问题吗?到目前为止,我认为所有答案都不太易读。将其提取成一个函数(接受一个字符串,返回布尔值或字符串),然后就再也不用担心它了。 - Caramiriel
10个回答

26

最易读的:

var thisval = $(this).val();
ao[id] = thisval === 'true' ? true : 
         thisval === 'false' ? false : 
         thisval;
根据条件运算符编写的一行代码:
var thisval = $(this).val();
ao[id] = thisval === 'true' ? true : (thisval === 'false' ? false : thisval);

基于 || 和 && 行为的一行代码:

var thisval = $(this).val();
ao[id] = thisval === 'true' || (thisval !== 'false') && thisval || false;

最短的一行代码(以上方法的组合):

var thisval = $(this).val();
ao[id] = thisval === 'true' || (thisval === 'false' ? false : thisval);

我认为第三种解决方案是最好的,因为即使我们不确定 thisval 是否是字符串,最后如果它不等于 true 或者 false,我们仍然可以假定 thisval 可能已经是一个 布尔值,如果不是的话,它也无法通过进一步的测试。 - svassr
@svassr 所有三个解决方案的行为都相同(对于任何输入都会给出完全相同的输出)。唯一的区别在于使用了哪些JS运算符。我相信通过适当的优化,它们甚至可能产生相同的字节码。 - Tibos
没错。我理解了,只是因为我同时读了关于该主题的三篇帖子,所以有点困惑 :p - svassr
@Gaspa79 这段代码与 OP 的代码等效 - 除了 'true' 和 'false' 之外的值会按原样返回。条件运算符不会强制执行有关结果类型的任何内容。在控制台中运行代码以自我验证 :D。 - Tibos
@Tibos 我改口了。问号运算符在强类型语言中的工作方式似乎与它在其他语言中的工作方式不同。之前给你点赞是正确的。谢谢。 - Gaspa79

12

请尝试使用JSON.parse()

"true""false"实际上是truefalsejson表示方式。这就是ajax将从服务器端作为字符串解析的json对象。如果在服务器端返回true,false =>浏览器将其作为字符串"true"或"false"(json表示形式)接收。

if ( $(this).val() == "true" ||  $(this).val() == "false") {
    ao[id] = JSON.parse($(this).val());
}else {
    ao[id] = $(this).val();
}

演示


仅仅为了解析一个你知道只可能是“true”或“false”的东西而使用JSON似乎有些过度了...另外,每次调用上面的代码时,.val()方法将被调用三次。 - Haroldo_OK
1
@Haroldo_OK:我认为这不是过度设计,这也是我们从服务器解析响应时使用的内容。 - Khanh TO
这也适用于数字,例如:JSON.parse('123') // 返回 123 - Alex
非常棒的回答!对一个非常常见的问题给出了非常创新的解决方案。 - undefined

3
String.prototype.bool = function() {
    return (/^true$/i).test(this);
};


if ( $(this).val() == "true" ||  $(this).val() == "false") {
    ao[id] = $(this).val().bool();
}else {
    ao[id] = $(this).val();
}

1
('' + thisval).toLowerCase() === 'true'

如果额外的字符串和 toLower 可以忽略不计,那么可能会很简单。

只有当它明确设置为 true(布尔值或不区分大小写的字符串)时才为真,否则为假。

 // so complete solution to get the same value if neither true nor false
const thisvalStr = ('' + thisval).toLowerCase();
a[id] = thisvalStr === 'true'? true: (thisvalStr === 'false')? false: thisval;

可以使用 || 或数组根据需要修改以包括其他值,如 1 等。
const TrueValuesStr = ['1', 'true']

TrueValueStr.contains(('' + thisval).toLowerCase() === 'true')

1
这可能会更加优雅:

稍微

var thisval = $(this).val();

if (thisval === "true" || thisval === "false") {
    thisval = (thisval === "true");
}

0

如果你想的话,你可以在一行代码中完成所有这些操作:

const getBool = value => value == "true" || value == "false" ? value == "true" : value;

getBool($(this).val());

解释

在 JavaScript 中,您可能会习惯使用类似以下的语句:

if(answer == "yes"){ ...

answer == "yes" 将会被计算为 true 或者 false

对于您的问题,这肯定可以帮助其中的一部分。如果只有 "true" 或者 "false" 这两个选项,那么就会非常简单:

const getBool = (value) => value == "true"
getBool("true"); // true
getBool("false"); // false

我们现在可以将其包装在三元运算符中,基本概述:
`if this` ? `then do this` : `if not, then do this`

所以我们检查值是真还是假,如果是,则使用上述技术。
value == "true" || value == "false" 

如果不是,我们可以直接返回该值而不进行任何修改。因此测试变成了:
value == "true" || value == "false" ? value == "true" : value;

0

我可能更喜欢

const parseMaybeBool = val =>
  typeof val === 'string'
    ? val.toLowerCase() === 'true' || val.toLowerCase() === 'false'
      ? Boolean(val)
      : val
    : val;

或带类型

const isBool = (val: unknown): val is boolean =>
  typeof val === 'boolean' ||
  (typeof val === 'string' &&
    (val.toLowerCase() === 'true' || val.toLowerCase() === 'false'));

const parseMaybeBool = (val: unknown) =>
  isBool(val) ? Boolean(val) : val;


0
var thisval = $(this).val();

switch(thisval) { 
case 'true' : 
    ao[id] = true; 
    break; 

case 'false' : 
    ao[id] = false; 
    break; 

default: 
    ao[id] = thisval; 

}

我会创建一个数组来保存字符串为 true 或 false 时的两个可能值。然后,我会搜索看看 thisval 是否在该数组中。如果不在,则 indexOf 函数将返回 -1。之后,只需要遍历这些值并构建您想要的情况即可。

编辑:根据 Tibos 的建议,我已更新代码。谢谢!


1
OP确实要求改进他的代码,那么改进在哪里呢? - Mark Walters
通常情况下,当有超过2个if语句时,使用switch语句可以获得更好的性能表现。这是我在回答问题时所记住的唯一一件事。我认为通过“改进的方式”,提问者指的是性能管理 :) - vladzam
这样做对性能的提升很小,几乎不会被注意到。在任何情况下缓存 $(this).val() 都是有用的,但我认为这段代码显得更加冗长。 - Mark Walters
Indexof会抵消使用switch而不是两个ifs所带来的所有性能优势。为什么不使用switch(thisval) { case 'true' : ao[id] = true; break; case 'false' : ao[id] = false; break; default: ao[id] = thisval; }呢? - Tibos
你说得对,Tibos!这样确实会更快!我会相应地更新代码。 - vladzam

0
在2022年美好的夏季,这是我会这样做的:
const thisval = $(this).val();

ao[id] = ['true', 'false'].includes(thisval) ? JSON.parse(thisval) : thisval;

你还可以更进一步,让它也处理数字:

ao[id] = ['true', 'false'].includes(thisval) || !Number.isNaN(Number(thisval))
  ? JSON.parse(thisval)
  : thisval;

-1
在Node.js中,通过使用{{link1:node-boolify}},我们可以使用isBoolean()和Boolify()。 验证结果
var isBoolean = require('node-boolify').isBoolean;

isBoolean(true); //true
isBoolean('true'); //true
isBoolean('TRUE'); //false
isBoolean(1); //true
isBoolean(2); //false
isBoolean(false); //true
isBoolean('false'); //true
isBoolean('FALSE'); //false
isBoolean(0); //true
isBoolean(null); //false
isBoolean(undefined); //false
isBoolean(); //false
isBoolean(''); //false

布尔转换结果

var Boolify = require('node-boolify').Boolify;

Boolify(true); //true
Boolify('true'); //true
Boolify('TRUE'); //null
Boolify(1); //true
Boolify(2); //null
Boolify(false); //false
Boolify('false'); //false
Boolify('FALSE'); //null
Boolify(0); //false
Boolify(null); //null
Boolify(undefined); //null
Boolify(); //null
Boolify(''); //null

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接