Питання Як я можу перетворити рядок на логічне у JavaScript?


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

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

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

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

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


1839
2017-11-05 00:13


походження


Просто виділити непарний приклад уникнення порівняння трьох рівних: у мене є функція currentSortDirection() що повертається 1 для висхідного сорту 0 для спадного сорту, і -1 бо не встановлено Використовуючи while (currentSortDirection() != desiredSortDirection) { sortColumn() } прекрасно працює, оскільки -1 != true  і  -1 != false... але змінити це на while (Boolean(currentSortDirection) !== ...) {...} сили -1 в a true, що вимагає додаткової пари рядків підготовки, щоб зробити jshint щасливим. - Droogans
"Чи є кращий спосіб досягти цього?" - звичайно, це гірший спосіб: D string=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse); - Mark K Cowan
Легко керуйте струнами та болтами: function parseBool(val) { return val === true || val === "true" } - WickyNilliams
@ Марк function checkBool(x) { if(x) {return true;} else {return false;} } - 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 використовуючи їх. Хоча вони найчистіші методи, якими я можу думати про булеву конверсію, я думаю, що вони не те, що ви шукаєте.


2472



myValue === 'true'; точно еквівалентно myValue == 'true';. Немає користі в користуванні === над == тут - Tim Down
я слідую Порада Крокфорда і використовувати === і !== коли це має сенс, що майже завжди. - guinaps
А як щодо "TRUE" у всіх великих регістрах, наприклад? - BMiner
@guinaps я зазвичай дотримуюсь поради Крокфорда, але це == проти === сценарій є одним з небагатьох, в якому я цього не роблю. Я повністю не погоджуюсь з тим, що це "майже завжди" має сенс використовувати ===. Легко набрані мови існувати тому що ми не хочемо піклуватися про тип; якщо ми перевіримо щось подібне 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%. Люди, які використовують ie7 у 15, очевидно, не дуже добре займаються інтернет-речі. підбадьорює - Todd
чому там так багато upvotes? Це неефективно і жахливо. Що далі? '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
@ Роберт, приємно, але я вважаю за краще за замовчуванням 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
@Томас Едінг фальшивий ... що ти хочеш, щоб він повернувся? - 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 я не погоджуюсь. Це саме той тип перевантаження прототипу для. Якщо ви боїтеся цього порушення (бідного) коду, на який покладається ... для цього, є способи приховувати властивості від переліку. Побачити Object.defineProperty. - devios1
Логічне синтаксичне аналізування не належить до класу String .. ви могли б мати справу з будь-якою кількістю аналізаторів сміття та перетворення там. -1 до змінних прототипів взагалі. -1 до рішень, які не працюють через крос-браузер. -1 за поганий дизайн. - Thomas W


Не забудьте зіставити справу:

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

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

var isTrueSet = document.myForm.IS_TRUE.checked;

Припускаючи, що якщо воно буде перевірено, він "встановлений" рівним істинному. Це оцінюється як true / false.


103



чому ти зробиш трійковий? у вас вже є логічний номер - nickf
Тому що ти можеш? Що ви маєте на увазі під "у вас вже є логічний там"? - Jared Farrish
Джаред, === вже є логічним станом, потрійний зайвий. - 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, якщо ви використовуєте перший метод. - DRaehal
Як швидко викидати "помилковий" рядок до false булеве значення з JSON.parse? З точки зору процесора, продуктивність пам'яті - Green


Ваше рішення добре.

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


29



Це єдино розумна відповідь тут :) - Bobby Jack
Чому ви думаєте, що це буде дурне використання ===? З точки зору продуктивності це буде точно так само, якщо обидва типи - це рядки. У всякому разі, я скоріше використовую === тому що я завжди уникаю використання == і !=. Обгрунтування: stackoverflow.com/questions/359494/... - Mariano Desanze
З тих пір value завжди буде a 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

UPDATE (без 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
Версія "без JSON" має дефект: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). замінити (!! 0, ''))); виробляє правду - Etienne
Добре, дякую. Я відремонтував його і створив скрипку jsfiddle.net/remunda/2GRhG - Jan Remunda
getBool(undefined) буде зламано при використанні оригінальної версії JSON і повернеться true для 2-ї версії. Ось третя версія, яка повертає false: функція getBool (val) {var num; повернути val = null && (! isNaN (num = + val)? !! num: !! String (val) .toLowerCase (). замінити (!! 0, '')); } - Ron Martinez