Як я можу перетворити рядок у boolean в JavaScript?


2549

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

У мене є прихована форма в HTML, яка оновлюється на основі вибору користувача у списку. Ця форма містить деякі поля, які представляють булеві значення та динамічно заповнюються властивим булевим значенням. Однак, як тільки це значення поміщається у приховане поле введення, воно стає рядком.

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

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

Чи є кращий спосіб досягти цього?


50
"Чи є кращий спосіб досягти цього?" - безумовно, є гірший шлях: Dstring=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse);
Марк К Кован

3
Легко обробляйте струни та булі:function parseBool(val) { return val === true || val === "true" }
WickyNilliams

1
@Markfunction checkBool(x) { if(x) {return true;} else {return false;} }
Sebi

2
@Sebi: Ви забули це задокументувати:if (checkBool(x) != false) { ... } else { ... }
Mark K Cowan

3
!!(parseInt(value) || value === "true")
Андрій Лука

Відповіді:


3474

Зробіть:

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

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

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

Не:

Вам, мабуть, слід бути обережними щодо використання цих двох методів для ваших конкретних потреб:

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

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

Будь-яка рядок, що не є порожньою рядком, оцінить true, використовуючи їх. Хоча вони є найчистішими методами, про які я можу подумати щодо булевої конверсії, я думаю, що вони не те, що ви шукаєте.


196
myValue === 'true';точно рівнозначно myValue == 'true';. Там немає ніякої вигоди в використанні ===більш ніж ==тут.
Тім Даун

551
Я дотримуюся порад і використання Крокфорда,=== і !==коли це має сенс, що майже завжди.
guinaps

55
Що, наприклад, "ІСТИНА" у всіх великих літерах?
BMiner

102
@guinaps Я зазвичай дотримуюся порад Крокфорда, але сценарій ==проти ===одного з небагатьох, у якому я цього не роблю. Я повністю не згоден, що це "майже завжди" має сенс використовувати ===. Мови з типовим типом існують, тому що ми не хочемо дбати про тип; якщо ми перевіряємо щось на кшталт, if (price >= 50)нам не байдуже, чи почалося це як рядок. Я кажу, більшість часу ми хочемо, щоб типи жонглювали. У рідкісних випадках, коли ми не хочемо типу "жонглювання" (наприклад if (price === null)), ми використовуємо ===. Це те, що я роблю роками, і ніколи у мене не було проблем.
JMTyler

169
@JMTyler може не помітити програміста з технічного обслуговування, що відбудеться після. Завжди використовуйте належного оператора порівняння! Якщо ви знаєте "напевно" типи з обох сторін, але не використовуєте ===, я не буду мати ці знання, коли переглядаєте ваш код пізніше. Якщо ваш код буде використаний повторно, це може стати кошмаром. Якщо ви дійсно хочете, щоб ваші типи були "жонгльованими", як ви говорите, тоді використовуйте "==", але занадто багато JS-розробників буде подолати це занадто легко, краще підтягнути код. Як часто я хочу, щоб рядок "false" означав булеву "true"?
aikeru

687

Увага

Це дуже upvoted спадщини відповідь є технічно правильним , але охоплює тільки дуже специфічний сценарій, коли ваша рядок значення ТОЧНО "true"або "false".

Недійсна рядок json, передана в ці функції нижче, ВИМАЄ виняток .


Оригінальна відповідь:

Як щодо?

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

або з jQuery

$.parseJSON("TRUE".toLowerCase());

62
Проблема в цьому полягає в тому, що багато потенційних значень генерують помилку розбору, яка зупиняє виконання JS. Так працює JSON.parse ("FALSE") бомби Javascript. Суть питання, я думаю, полягає не в тому, щоб просто вирішувати ці точні випадки, а також бути стійкими до інших справ.
BishopZ

3
@ Luke це рішення насправді саме те, що мені було потрібно; ну, завернувши його в спробу ... все ж зловити. Я хотів перетворити на bool, лише якщо це булеве значення в рядку; в іншому випадку просто використовуйте наданий рядок. Це працює! Дякую.
jedmao

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
@Robert, приємний, але я б швидше мав за замовчуванням falseзамість цього.
drigoangelo

@drigoangelo default: return true;Звичайно, це можливо. Але це змінило б поведінку функції.
Роберт

2
Я подумав , що це найкраща відповідь, і хотів би зупинитися на цьому тут: stackoverflow.com/questions/263965 / ...
BrDaHa

9
якщо ви нормалізуєте дані, зателефонувавши до .toLowerCase (), ви, можливо, захочете також кинути обрізку (), щоб знімати пробіл
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

20
Коли ви можете отримати рядок у верхньому регістрі або String(a).toLowerCase() === 'true'
булевому значенні

String("what about input like this that isn't a bool?") == "true"
Томас Едінг

6
@ThomasEding false ... що ви хочете, щоб він повернувся?
Снігопалення

2
можна було навіть скоротити, не використовуючи String()конструктор:true+'' === 'true' // true
Тодд

1
До речі, для 1 або 0 він також має бути неправдивим або правдивим
Мігель

128

Не забудьте відповідати випадку:

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

Крім того, якщо це прапорець елемента форми, ви також можете виявити, чи встановлено прапорець:

var isTrueSet = document.myForm.IS_TRUE.checked;

Якщо припустити, що якщо він встановлений, він встановлюється рівним істинному. Це визначається як істинне / хибне


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 показує помилкові, в той час як Opera, Chrome, Safari та IE показують правду. Bug 720760 )


10
Ви завжди можете префіксувати функцію, якщо боїтесь, що вона буде заважати іншому коду. Якщо якийсь код все-таки порушується, цей код є надто крихким і його слід виправити. Якщо ваша додана функція робить об'єкт занадто важким, коли це спричиняє проблеми з продуктивністю для іншого коду, тоді, очевидно, ви цього не хочете робити. Але, я не думаю, що це взагалі погана ідея розширювати вбудовані об'єкти. Вони також не підлягали б публічному поширенню, якби це було так.
Shadow2531

41
@DTrejo @Szymon Я не згоден. Це саме та річ, яка перевантажує прототип. Якщо ви боїтеся, щоб він зламав (поганий) код, на який покладається for..in, є способи приховати властивості від перерахування. Див Object.defineProperty.
devios1

Для дотримання конвенції я б назвав цеparseBool
гузарт

8
Булевий синтаксичний розбір не належить до класу String .. ви б закінчилися з будь-якою кількістю сміттєвих аналізаторів та перетворенням. -1 до зміни прототипів взагалі. -1 до рішень, які не працюють крос-браузером. -1 за поганий дизайн.
Thomas W

1
Ось порівняння продуктивності всіх відповідей. stackoverflow.com/a/28588344/2824333
sospedra

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" рядок до falseбулевого значення JSON.parse? З точки зору процесора, продуктивність пам’яті
Зелений

Чи не було б легше почати з if (str) {...} усунути все, що вже є помилковим? І всередині цього, якщо умова, просто потрібно турбуватися про повернення істини, адже ви вже закінчуєтесь поверненням помилковим!
Ларфоїд

Майте на увазі, що ви можете скоротити багато тестів рядків до (["true", "так", "1"]. IndexOf (str.toLowerCase (). Trim ())! = -1) та використовувати резервний Булева (str), щоб висвітлити такі речі, як 'null'
Скотт,

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


Я використовую цей, оскільки він охоплює речі, які ви отримуєте від атрибутів 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 (). замінити (!! 0, ''))); виробляє правду
Етьєн

3
getBool(undefined)при збої оригінальної версії JSON повернеться істинною для другої версії. Ось 3-я версія, яка повертає false: функція getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). замінити (!! 0, '')); }
Рон Мартінес

31

Ваше рішення прекрасне.

Використання ===в цьому випадку було б просто нерозумним, оскільки поле valueзавжди буде а String.


17
Чому ви вважаєте, що це було б нерозумно ===? З точки зору продуктивності було б точно однаково, якби обидва типи - це рядки. У будь-якому разі я скоріше використовую, ===оскільки завжди уникаю використання ==та !=. Обгрунтування: stackoverflow.com/questions/359494 / ...
Маріано Desanze

3
Оскільки valueзавжди буде stringні ==ні ===, ні дурні. Обидва є правильним інструментом для цієї роботи. Вони відрізняються лише тоді, коли типи не рівні. У такому випадку ===просто повертається falseпід час ==виконання алгоритму примусового вимушеного типу перед порівнянням.
Роберт

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

20

Булевий об'єкт не має методу "розбору". Boolean('false')повертає істину, тому це не спрацює. !!'false'також повертається true, так що також не буде працювати.

Якщо ви хочете, щоб рядок 'true'повертав булева, trueа рядок 'false'повертав булева false, тоді найпростішим рішенням є використання eval(). eval('true')повертає істинне і eval('false')повертає хибне. Майте на увазі наслідки для продуктивності при використанні eval().


Щоб зрозуміти, що "неправильно" (або правильно) з eval, ознайомтеся з такими статтями, як javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval або шукайте в stackoverflow для "Javascript eval malware"
GrahamMc

2
Я згоден, var isTrueSet = (myValue === 'true');це найкраща відповідь.
thoan

Мені подобається, що це лаконічно. Але це не вдається ефектно для основного випадку 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;
thoan

1
@ 10basetom: Цілком правильно. Ви повинні включити .toLowerCase()у відповідь мою думку. Я нічого не намагаюся змусити. Верхній регістр TRUE- достатньо поширене значення, яке може повернутися багатьма віджетами інтерфейсу користувача.
Сніговик

17

Це було взято з прийнятої відповіді, але насправді це дуже слабке місце, і я шокований, як у нього з’явився цей підрахунок оновлень, проблема з цим, що ви повинні розглянути випадок рядка, оскільки це враховує регістр

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

16

Я використовую наступне:

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

Ця функція виконує звичайний булевий примус за винятком рядків "false" (регістр нечутливий) та "0".


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

12

Для перетворення обох рядків ("true", "false") і boolean в boolean

('' + 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)));


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"

Це добре, але працює лише з типом String. Уявіть, що для цього потрібно використовувати змінну, яка може бути "true"або true. Якщо прийде другий, це не вийде. Чи можливо зробити так, document.prototypeщоб використовувати це там, де ми цього хочемо?
MarceloBarbosa

Це виглядає елегантно. Чудова робота! Однак я помітив, що перевантаження базових прототипів у великих програмах JS (які також потребують тестування одиниць) може спричинити за собою деяку несподівану поведінку (а саме, коли ви хочете перебрати "за" через масив, який перевантажив прототип, ви отримаєте деякі властивості, які ви зазвичай не очікували). Вас попередили ;)
cassi.lup

Ваш варіант, який приймає булева функція StringOrElse2Bool (sob) {if (typeof sob === "string") {return ["ні", "false", "0", "off"]. indexOf (sob.toLowerCase ())! == -1? хибно: правда; } else {return !!
sob

8

Руками вниз найпростішим способом (якщо припустити, що рядок буде "вірно" або "помилково"):

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", які є "truthy" та "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, де їм потрібно перейти від рядкових дозорних до нативного типу та зробіть там порівняння, бажано там, де це робиться лише один раз для кожного значення, яке потрібно перетворити. Не забудьте вирішити, що має статися, якщо дозорний рядок не той, про який знає сценарій (тобто чи ти за замовчуванням відповідає true або false?)

Іншими словами, так, вам потрібно залежати від значення рядка. :-)


7

Думаю, що це питання має на меті задовольнити три завдання:

  • Поверніть true / false для truthy та falsey значень, але також поверніть true / false для кількох рядкових значень, які були б truthy або falsey, якби вони були булевими, а не рядковими.
  • По-друге, надайте еластичний інтерфейс, щоб значення, відмінні від зазначених, не вийшли з ладу, а швидше повернули значення за замовчуванням
  • По-третє, робіть все це якомога менше коду.

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

JSON.parse("FALSE") // fails

Це рішення недостатньо стисло:

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

Я працюю над вирішенням цієї точної проблеми для Typecast.js . І найкраще рішення для всіх трьох цілей:

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

Він працює у багатьох випадках, не виходить з ладу, коли передаються такі значення, як {}, і є дуже стислим. Крім того, він повертає false як значення за замовчуванням, а не невизначене або викидання помилки, що є більш корисним у розробленому Javascript JavaScript. Браво на інші відповіді, які це запропонували!


Тільки для того, щоб повернутися до своїх цілей, єдина проблема вашого третього та найкращого рішення полягає в тому, що він не відповідає Цілі №1 - він поверне справжнє лише для значення 'true', але не для будь-яких правдивих даних. Для того, щоб він відповідав Цілі №1, він лише трохи більш стислий, ніж рішення №2, і набагато менш читабельний.
JMTyler

return /^(true|yes|1|t|y)$/i.test(str);
Кевін Баучер

7

Я трохи запізнююся, але у мене є невеликий фрагмент, щоб зробити це, він по суті підтримує всі JScripts truthey / falsey / брудні, але включає "false"як прийнятне значення для false.

Я віддаю перевагу цьому методу перед згаданим, оскільки він не покладається на третю сторону для розбору коду (тобто: 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..

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.