Могу ли я преобразовать строку, представляющую логическое значение (например, 'true', 'false') во внутренний тип в JavaScript?
У меня есть скрытая форма в HTML, которая обновляется на основе выбора пользователя в списке. Эта форма содержит некоторые поля, которые представляют логические значения и динамически заполняются внутренним логическим значением. Однако, как только это значение помещается в скрытое поле ввода, оно становится строкой.
Единственный способ определить логическое значение поля после его преобразования в строку - это зависеть от литерального значения его строкового представления.
var myValue = document.myForm.IS_TRUE.value;
var isTrueSet = myValue == 'true';
Есть ли лучший способ сделать это?
Делать:
var isTrueSet = (myValue == 'true');
Вы можете сделать его более строгим, используя оператор идентификации ( ===
), который не выполняет никаких неявных преобразований типов, когда сравниваемые переменные имеют разные типы, вместо оператора равенства ( ==
).
var isTrueSet = (myValue === 'true');
Не рекомендуется:
Вы, вероятно, должны быть осторожны при использовании этих двух методов для ваших конкретных потребностей:
var myBool = Boolean("false"); // == true
var myBool = !!"false"; // == true
Любая строка, которая не является пустой строкой, будет оценена true
с использованием их. Хотя это самые чистые методы, которые я могу придумать в отношении логического преобразования, я думаю, что это не то, что вы ищете.
myValue === 'true';
точно эквивалентно myValue == 'true';
. Там нет никакой выгоды в использовании ===
более чем ==
здесь. ===
и !==
всякий раз, когда это имеет смысл, что почти всегда. ==
против» ===
- один из немногих, в которых я не участвую . Я совершенно не согласен с тем, что его «почти всегда» имеет смысл использовать ===
. Существуют слабо типизированные языки, потому что мы не хотим заботиться о типе; если мы проверяем что-то вроде этого, if (price >= 50)
нам все равно, начинается ли оно как строка. Я говорю, что в большинстве случаев мы хотим , чтобы типы были подтасованы. В тех редких случаях, когда мы не хотим жонглировать типами (например if (price === null)
), тогда мы используем ===
. Это то, что я делал годами, и у меня никогда не было проблем. var myBool = Boolean.parse("true");
или
var myBool = Boolean("true");
или
var myBool = !!"true";
Не уверен, что первый относится к IE.
!!
, также ненадежен. !!"true";
вернется, true
но так будет !!"false";
и !!"abc";
. Когда JavaScript обрабатывает строку с помощью 'true'
или 'false'
он не различает эти значения. Он просто видит их как строки со значением. Поэтому , используя !
оператор на строку : !'anyValue'
и даже !' '
будет всегда быть false
и только !''
будет true
. Не забудьте сопоставить регистр:
var isTrueSet = (myValue.toLowerCase() === 'true');
Кроме того, если это флажок элемента формы, вы также можете определить, установлен ли флажок:
var isTrueSet = document.myForm.IS_TRUE.checked;
Предполагая, что, если это проверено, это "установлено" равным true. Это оценивается как истина / ложь.
myValue
произойдет null
, true
или какой-то другой тип ...Ваше решение в порядке.
Использование ===
в этом случае будет просто глупым, так как поле value
всегда будет a String
.
===
? С точки зрения производительности было бы точно так же, если оба типа являются строками. Во всяком случае, я скорее использую, ===
так как я всегда избегаю использования ==
и !=
. Обоснования: stackoverflow.com/questions/359494/…value
всегда будет string
ни ==
ни ===
глупо. Оба являются правильным инструментом для этой работы. Они отличаются только тогда, когда типы не равны. В этом случае ===
просто возвращает false
while, ==
выполняя сложный алгоритм приведения типа перед сравнением. Вы должны отделить (в своем мышлении) значение вашего выбора и представление этого значения.
Выберите точку в логике JavaScript, где им нужно перейти от строковых сторожей к нативному типу, и проведите там сравнение, предпочтительно там, где это делается только один раз для каждого значения, которое необходимо преобразовать. Не забудьте указать, что должно произойти, если строка sentinel не та, которую знает сценарий (т. Е. Используется ли по умолчанию значение true или false?)
Другими словами, да, вам нужно зависеть от значения строки. :-)
Если есть какой-то другой код, который преобразует логическое значение в строку, вам нужно точно знать, как этот код хранит значения true / false. Либо это, либо вам нужен доступ к функции, которая обращает это преобразование.
Существует бесконечно много способов представления логических значений в строках («истина», «Y», «1» и т. Д.). Поэтому вам не следует полагаться на какой-либо универсальный преобразователь строки в логическое значение, например, Boolean (myValue). Вам нужно использовать подпрограмму, которая обращает исходное преобразование логическое-строковое, что бы это ни было.
Если вы знаете, что он преобразует истинные логические значения в «истинные» строки, тогда ваш пример кода в порядке. За исключением того, что вы должны использовать === вместо ==, чтобы не было автоматического преобразования типов.
Вы можете использовать регулярные выражения:
/*
* 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 показывает false, тогда как Opera, Chrome, Safari и IE показывают true. Ошибка 720760 )
Object.defineProperty
. parseBool
Я думаю, что это очень универсально:
if (String(a) == "true")
...
Идет:
String(true) == "true" //returns true
String(false) == "true" //returns false
String("true") == "true" //returns true
String("false") == "true" //returns false
String(a).toLowerCase() === 'true'
String("what about input like this that isn't a bool?") == "true"
String()
конструктор:true+'' === 'true' // true
if (String(a) == "true"){
//true block
} else {
//false block
}
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);
}
}
"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;}
false
. default: return true;
, безусловно, возможно. Но это изменило бы поведение функции. Просто сделайте:
var myBool = eval (yourString);
Примеры:
alert (eval ("true") == true); // TRUE
alert (eval ("true") == false); // FALSE
alert (eval ("1") == true); // TRUE
alert (eval ("1") == false); // FALSE
alert (eval ("false") == true); // FALSE;
alert (eval ("false") == false); // TRUE
alert (eval ("0") == true); // FALSE
alert (eval ("0") == false); // TRUE
alert (eval ("") == undefined); // TRUE
alert (eval () == undefined); // TRUE
Этот метод обрабатывает пустую строку и неопределенную строку естественным образом, как если бы вы объявили переменную без присвоения ей значения.
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.");
}
};
function parseBoolean
вместо этого создайте новоеСледующего будет достаточно
String.prototype.boolean = function() {
return "true" == this;
};
"true".boolean() // returns true "false".boolean() // returns false
Логический объект не имеет метода parse. Boolean('false')
возвращает true, так что это не сработает. !!'false'
также возвращается true
, так что это тоже не сработает.
Если вы хотите, чтобы строка 'true'
возвращала логическое значение, true
а строка 'false'
возвращала логическое значение false
, то самое простое решение - использовать eval()
. eval('true')
возвращает true и eval('false')
возвращает false. Имейте в виду последствия для производительности при использовании, eval()
хотя.
var isTrueSet = (myValue === 'true');
это лучший ответ. eval('TRUE')
; доказывая еще раз, это eval()
зло. JSON.parse('TRUE')
из приведенного ниже ответа также впечатляет. Довольно просто вызвать условие ошибки в JavaScript (или любом другом языке). Чтобы учесть это, вы должны сначала нормализовать строку, например,var myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
.toLowerCase()
в ответ мою точку зрения. Я не пытаюсь ничего форсировать. Прописные буквы TRUE
- это достаточно распространенное значение, которое возвращают многие виджеты пользовательского интерфейса. Руки проще всего (при условии, что ваша строка будет 'true' или 'false'):
var z = 'true';
var y = 'false';
var b = (z === 'true'); // will evaluate to true
var c = (y === 'true'); // will evaluate to false
Всегда используйте оператор === вместо оператора == для этих типов преобразований!
function returnBoolean(str){
str=str.toString().toLowerCase();
if(str=='true' || str=='1' || str=='yes' || str=='y' || str=='on' || str=='+'){
return(true);
}
else if(str=='false' || str=='0' || str=='no' || str=='n' || str=='off' || str=='-'){
return(false);
}else{
return(undefined);
}
}
Предупреждение
Этот устаревший ответ с большим количеством голосов является технически правильным, но он охватывает только очень специфический сценарий, когда ваше строковое значение ТОЧНО "true"
или "false"
.
Недопустимая строка json, переданная в эти функции ниже, вызовет исключение .
Оригинальный ответ:
Как насчет?
JSON.parse("True".toLowerCase());
или с помощью jQuery
$.parseJSON("TRUE".toLowerCase());
JSON.parse("TRUE".toLowerCase())
чтобы он мог правильно разобрать. 'true'.length === 4
? 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
// просто чтобы быть увереннымЯ обнаружил, что использование «1» и пустого значения «» для логических значений работает гораздо более предсказуемо, чем «истинные» или «ложные» строковые значения ... особенно с HTML-формами, поскольку неинициализированные / пустые значения в элементах Dom будут последовательно оценивать в ложь, тогда как любое значение в них оценивается как истина.
Например:
<input type='button' onclick='this.value = tog(this.value);' />
<script type="text/javascript">
function tog(off) {
if(off) {
alert('true, toggle to false');
return '';
} else {
alert('false, toggle to true');
return '1';
}
}
</script>
Просто казалось, что это более легкая дорога, но до сих пор она была очень последовательной / легкой ... может быть, кто-то может найти способ сломать это?
Как сказал @ Shadow2531, вы не можете просто конвертировать его напрямую. Я бы также предложил, чтобы вы рассматривали строковые входы помимо «true» и «false», которые являются «truey» и «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;
}
}
@guinaps> Любая строка, которая не является пустой строкой, будет иметь значение true, используя их.
Как насчет использования метода String.match ()
var str="true";
var boolStr=Boolean(str.match(/^true$/i));
одно это не получит 1/0 или да / нет, но оно также поймает ИСТИНА / истина, а также вернет ложь для любой строки, в которой в качестве подстроки указано «истина».
РЕДАКТИРОВАТЬ
Ниже приведена функция для обработки истина / ложь, 1/0, да / нет (без учета регистра)
function stringToBool(str) {
var bool;
if (str.match(/^(true|1|yes)$/i) !== null) {
bool = true;
} else if (str.match(/^(false|0|no)*$/i) !== null) {
bool = false;
} else {
bool = null;
if (console) console.log('"' + str + '" is not a boolean value');
}
return bool;
}
stringToBool('1'); // true
stringToBool('No'); // false
stringToBool('falsey'); // null ("falsey" is not a boolean value.)
stringToBool(''); // false
/^(false|0|no)*$/i
будет соответствовать пустой (которая может быть намерение) , но и совпадает с любым количеством false
, 0
или no
, например , "0falseno0nofalse0"
будет также оценить, false
но следует оценить, null
и вывод сообщения консоли что это не булево значение. Boolean.parse()
существует в некоторых реализациях браузера. Он определенно не универсален, поэтому, если это то, что вам нужно, вы не должны использовать этот метод. Но в Chrome, например (я использую v21) он работает просто отлично, как и следовало ожидать.
Boolean("false")
=>true
Я использовал этот фрагмент для преобразования чисел и логических значений:
var result = !isNaN(value) ? parseFloat(value) : /^\s*(true|false)\s*$/i.exec(value) ? RegExp.$1.toLowerCase() === "true" : value;
Выражение, которое вы ищете, просто
/^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
Мой взгляд на этот вопрос заключается в том, что он направлен на достижение трех целей:
- Верните true / false для значений truey и falsey, но также верните true / false для нескольких строковых значений, которые были бы true или false, если бы они были булевыми, а не строковыми.
- Во-вторых, предоставьте упругий интерфейс, чтобы значения, отличные от указанных, не сработали, а вернули значение по умолчанию
- В-третьих, делайте все это, используя как можно меньше кода.
Проблема с использованием JSON заключается в том, что он не работает, вызывая ошибку Javascript. Это решение не является устойчивым (хотя оно удовлетворяет 1 и 3):
JSON.parse("FALSE") // fails
Это решение не является достаточно кратким:
if(value === "TRUE" || value === "yes" || ...) { return true; }
Я работаю над решением этой проблемы для Typecast.js . И лучшее решение для всех трех целей это:
return /^true$/i.test(v);
Он работает во многих случаях, не дает сбоя при передаче значений типа {} и очень лаконичен. Кроме того, он возвращает значение false в качестве значения по умолчанию, а не неопределенного значения или выдачи ошибки, что более полезно при разработке свободно написанного Javascript. Браво на другие ответы, которые предложили это!
'true'
, но не для любого достоверного ввода. Для того, чтобы оно соответствовало Задаче № 1, оно лишь немного более кратко, чем Решение № 2, и гораздо менее читабельно. return /^(true|yes|1|t|y)$/i.test(str);
Основываясь на ответе Стивена выше, я написал эту функцию как универсальный парсер для ввода строки:
parse:
function (value) {
switch (value && value.toLowerCase()) {
case null: return null;
case "true": return true;
case "false": return false;
default: try { return parseFloat(value); } catch (e) { return value; }
}
}
Вам даже не нужно преобразовывать строку в логическое значение. просто используйте следующее:
var yourstring = yourstringValue == 1 ? true : false;
я написал вспомогательную функцию, которая обрабатывает ваши дела (и некоторые другие). Не стесняйтесь изменять его в соответствии с вашими потребностями
/**
* @example
* <code>
* var pageRequestParams = {'enableFeatureX': 'true'};
* toBool(pageRequestParams.enableFeatureX); // returns true
*
* toBool(pageRequestParams.enableFeatureY, true, options.enableFeatureY)
* </code>
* @param {*}value
* @param {Boolean}[mapEmptyStringToTrue=false]
* @param {Boolean}[defaultVal=false] this is returned if value is undefined.
*
* @returns {Boolean}
* @example
* <code>
* toBool({'enableFeatureX': '' }.enableFeatureX); // false
* toBool({'enableFeatureX': '' }.enableFeatureX, true); // true
* toBool({ }.enableFeatureX, true); // false
* toBool({'enableFeatureX': 0 }.enableFeatureX); // false
* toBool({'enableFeatureX': '0' }.enableFeatureX); // false
* toBool({'enableFeatureX': '0 ' }.enableFeatureX); // false
* toBool({'enableFeatureX': 'false' }.enableFeatureX); // false
* toBool({'enableFeatureX': 'falsE ' }.enableFeatureX); // false
* toBool({'enableFeatureX': 'no' }.enableFeatureX); // false
*
* toBool({'enableFeatureX': 1 }.enableFeatureX); // true
* toBool({'enableFeatureX': '-2' }.enableFeatureX); // true
* toBool({'enableFeatureX': 'true' }.enableFeatureX); // true
* toBool({'enableFeatureX': 'false_' }.enableFeatureX); // true
* toBool({'enableFeatureX': 'john doe'}.enableFeatureX); // true
* </code>
*
*/
var toBool = function (value, mapEmptyStringToTrue, defaultVal) {
if (value === undefined) {return Boolean(defaultVal); }
mapEmptyStringToTrue = mapEmptyStringToTrue !== undefined ? mapEmptyStringToTrue : false; // default to false
var strFalseValues = ['0', 'false', 'no'].concat(!mapEmptyStringToTrue ? [''] : []);
if (typeof value === 'string') {
return (strFalseValues.indexOf(value.toLowerCase().trim()) === -1);
}
// value is likely null, boolean, or number
return Boolean(value);
};
MyLib.Convert.bool = function(param) {
var res = String(param).toLowerCase();
return !(!Boolean(res) || res === "false" || res === "0");
};
Вот моя 1 строка представления: мне нужно было оценить строку и вывод, true, если 'true', false, если 'false', и число, если что-нибудь вроде '-12.35673'.
val = 'false';
val = /^false$/i.test(val) ? false : ( /^true$/i.test(val) ? true : val*1 ? val*1 : val );
Я использую следующее:
function parseBool(b) {
return !(/^(false|0)$/i).test(b) && !!b;
}
Эта функция выполняет обычное логическое приведение, за исключением строк «false» (без учета регистра) и «0».
string=(string==String(string?true:false))?(string?true:false):(!string?true:false);
function parseBool(val) { return val === true || val === "true" }
function checkBool(x) { if(x) {return true;} else {return false;} }
if (checkBool(x) != false) { ... } else { ... }
!!(parseInt(value) || value === "true")