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

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

一旦字段转换为字符串,我唯一能找到的确定它的布尔值的方法就是依赖于它的字符串表示的文字值。

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

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


当前回答

以下内容就足够了

String.prototype.boolean = function() {
    return "true" == this; 
};

"true".boolean() // returns true "false".boolean() // returns false

其他回答

许多现有答案使用与此语义相似的方法,但我认为值得一提的是,以下“一行”通常就足够了。例如,除了OP的情况(表单中的字符串)外,人们还经常希望从NodeJS中的process.env中读取环境变量(据我所知,其值始终是字符串),以便启用或禁用某些行为,并且这些变量的格式通常为SOME_env_VAR=1。

const toBooleanSimple = (input) => 
  ['t', 'y', '1'].some(truePrefix => truePrefix === input[0].toLowerCase());

一个稍微更健壮、更具表现力的实现可能如下所示:

/**
 * Converts strings to booleans in a manner that is less surprising
 * to the non-JS world (e.g. returns true for "1", "yes", "True", etc.
 * and false for "0", "No", "false", etc.)
 * @param input
 * @returns {boolean}
 */
function toBoolean(input) {
  if (typeof input !== 'string') {
    return Boolean(input);
  }
  const s = input.toLowerCase();
  return ['t', 'y', '1'].some(prefix => s.startsWith(prefix));
}

对此的(玩笑)单元测试可能如下所示:

describe(`toBoolean`, function() {
  const groups = [{
    inputs: ['y', 'Yes', 'true', '1', true, 1],
    expectedOutput: true
  }, {
    inputs: ['n', 'No', 'false', '0', false, 0],
    expectedOutput: false
  }]
  for (let group of groups) {
    for (let input of group.inputs) {
      it(`should return ${group.expectedOutput} for ${JSON.stringify(input)}`, function() {
        expect(toBoolean(input)).toEqual(group.expectedOutput);
      });
    }      
  }
});

布尔对象没有“parse”方法。布尔值('false')返回true,因此这不起作用。!!'false'也返回true,因此这也不起作用。

如果您希望字符串“true”返回布尔值true,而字符串“false”返回布尔型false,那么最简单的解决方案是使用eval()。eval('true')返回true,eval('false')返回false。

不过,在使用eval()时,请记住性能和安全性的影响。

如果有其他代码将布尔值转换为字符串,您需要确切地知道该代码如何存储真/假值。要么这样,要么您需要访问反转转换的函数。

有无数种方法可以在字符串中表示布尔值(“true”、“Y”、“1”等)。因此,您不应该依赖一些通用的字符串到布尔值转换器,如布尔值(myValue)。您需要使用一个例程来反转原始布尔值到字符串的转换,无论是什么。

如果您知道它将真布尔值转换为“真”字符串,那么您的示例代码就可以了。除了您应该使用==而不是==,因此没有自动类型转换。

注意,也许将来代码会更改并返回布尔值,而不是当前的一个字符串。

解决方案是:

//Currently
var isTrue = 'true';
//In the future (Other developer change the code)
var isTrue = true;
//The solution to both cases
(isTrue).toString() == 'true'

在一行代码中将字符串转换为布尔值的最快安全方法

有助于加快Javascript中代码执行的一个特性是短路评估:

当逻辑表达式从左到右求值时,使用以下规则对其进行可能的“短路”求值测试:false&(任何东西)短路评估为false。true||(任何东西)被短路评估为真。

因此,如果您想在JSON.parse测试方式中测试字符串值是否为true或false,并保持强大的性能,则可以使用||运算符在测试值为布尔类型的情况下将慢速代码排除在执行之外。

test === true || ['true','yes','1'].indexOf(test.toString().toLowerCase()) > -1

由于Array.prototype.indexOf()方法是第5版ECMA-262标准的一部分,您可能需要一个polyfill来支持旧浏览器。

// Production steps of ECMA-262, Edition 5, 15.4.4.14
// Reference: http://es5.github.io/#x15.4.4.14
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(searchElement, fromIndex) {

    var k;

    // 1. Let O be the result of calling ToObject passing
    //    the this value as the argument.
    if (this == null) {
      throw new TypeError('"this" is null or not defined');
    }

    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get
    //    internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If len is 0, return -1.
    if (len === 0) {
      return -1;
    }

    // 5. If argument fromIndex was passed let n be
    //    ToInteger(fromIndex); else let n be 0.
    var n = +fromIndex || 0;

    if (Math.abs(n) === Infinity) {
      n = 0;
    }

    // 6. If n >= len, return -1.
    if (n >= len) {
      return -1;
    }

    // 7. If n >= 0, then Let k be n.
    // 8. Else, n<0, Let k be len - abs(n).
    //    If k is less than 0, then let k be 0.
    k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

    // 9. Repeat, while k < len
    while (k < len) {
      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the
      //    HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      //    i.  Let elementK be the result of calling the Get
      //        internal method of O with the argument ToString(k).
      //   ii.  Let same be the result of applying the
      //        Strict Equality Comparison Algorithm to
      //        searchElement and elementK.
      //  iii.  If same is true, return k.
      if (k in O && O[k] === searchElement) {
        return k;
      }
      k++;
    }
    return -1;
  };
}