Câu hỏi Làm thế nào tôi có thể chuyển đổi một chuỗi thành boolean trong JavaScript?


Tôi có thể chuyển đổi một chuỗi biểu thị giá trị boolean (ví dụ: 'true', 'false') thành một loại nội tại trong JavaScript không?

Tôi có một biểu mẫu ẩn trong HTML được cập nhật dựa trên lựa chọn của người dùng trong danh sách. Biểu mẫu này chứa một số trường đại diện cho các giá trị boolean và được điền động với giá trị boolean nội tại. Tuy nhiên, khi giá trị này được đặt vào trường nhập ẩn, nó sẽ trở thành một chuỗi.

Cách duy nhất tôi có thể tìm thấy để xác định giá trị boolean của trường, một khi nó được chuyển đổi thành một chuỗi, là phụ thuộc vào giá trị chữ của biểu diễn chuỗi của nó.

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

Có cách nào tốt hơn để thực hiện việc này không?


1840
2017-11-05 00:13


gốc


Chỉ để làm nổi bật một ví dụ kỳ lạ về việc tránh so sánh ba lần: tôi có một hàm currentSortDirection() trả về 1 cho một loại tăng dần, 0 cho một loại giảm dần và -1 không được thiết lập. Sử dụng while (currentSortDirection() != desiredSortDirection) { sortColumn() } hoạt động tốt, kể từ -1 != true  và  -1 != false... nhưng thay đổi thành while (Boolean(currentSortDirection) !== ...) {...} lực lượng -1 thành một true, đòi hỏi thêm một vài dòng chuẩn bị, chỉ để làm cho jshint hạnh phúc. - Droogans
"Có cách nào tốt hơn để thực hiện việc này không?" - chắc chắn có một cách tồi tệ hơn: D string=(string==String(string?true:false))?(string?true:false):(!string?true:fa‌​lse); - Mark K Cowan
Dễ dàng xử lý chuỗi và bools: function parseBool(val) { return val === true || val === "true" } - WickyNilliams
@Dấu function checkBool(x) { if(x) {return true;} else {return false;} } - Sebi
@ Sebi: Bạn quên ghi lại tài liệu: if (checkBool(x) != false) { ... } else { ... } - Mark K Cowan


Các câu trả lời:


Thực hiện:

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

Bạn có thể làm cho nó chặt chẽ hơn bằng cách sử dụng toán tử nhận dạng (===), không thực hiện bất kỳ chuyển đổi loại tiềm ẩn nào khi các biến được so sánh có các loại khác nhau, thay vì toán tử bình đẳng (==).

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

Không:

Có lẽ bạn nên thận trọng khi sử dụng hai phương pháp này cho các nhu cầu cụ thể của bạn:

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

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

Bất kỳ chuỗi nào không phải là chuỗi rỗng sẽ đánh giá true bằng cách sử dụng chúng. Mặc dù chúng là những phương pháp sạch nhất mà tôi có thể nghĩ đến liên quan đến chuyển đổi boolean, tôi nghĩ rằng chúng không phải là những gì bạn đang tìm kiếm.


2473



myValue === 'true'; tương đương chính xác với myValue == 'true';. Không có lợi ích khi sử dụng === kết thúc == đây. - Tim Down
Tôi theo Lời khuyên của Crockford Và sử dụng === và !== bất cứ khi nào nó có ý nghĩa, hầu như luôn luôn như vậy. - guinaps
Điều gì về "TRUE" trong tất cả các chữ hoa, ví dụ? - BMiner
@guinaps Tôi thường làm theo lời khuyên của Crockford, nhưng == so với === kịch bản là một trong số ít trong đó tôi không có. tôi hoàn toàn không đồng ý rằng nó "hầu như luôn luôn" có ý nghĩa để sử dụng ===. Ngôn ngữ được nhập sai hiện hữu bởi vì chúng tôi không muốn quan tâm đến loại; nếu chúng ta kiểm tra một cái gì đó như if (price >= 50) chúng tôi không quan tâm nếu nó bắt đầu như một chuỗi. Tôi nói, phần lớn thời gian, chúng tôi muốn loại được tung hứng. Trong những trường hợp hiếm hoi mà chúng tôi không muốn tung hứng kiểu (ví dụ: if (price === null)), sau đó chúng tôi sử dụng ===. Đây là những gì tôi đã làm trong nhiều năm và tôi đã không bao giờ đã có một vấn đề. - JMTyler
@ JMTyler có thể được xem xét các lập trình viên bảo trì đến sau. Luôn sử dụng toán tử so sánh phù hợp! Nếu bạn biết 'chắc chắn' các loại trên cả hai mặt, nhưng không sử dụng ===, tôi sẽ không có kiến ​​thức đó khi xem mã của bạn sau này. Nếu mã của bạn được tái sử dụng thì điều này có thể trở thành cơn ác mộng. Nếu bạn thực sự muốn loại của bạn 'juggled' như bạn nói, sau đó sử dụng '==', nhưng quá nhiều JS devs sẽ đi trên này quá dễ dàng, tốt hơn để thắt chặt mã của bạn. Bao lâu tôi muốn chuỗi 'sai' để biểu thị boolean 'true'? - aikeru


Cảnh báo

Câu trả lời thừa kế được đánh giá cao này về mặt kỹ thuật là chính xác nhưng chỉ bao gồm một kịch bản rất cụ thể, khi giá trị chuỗi của bạn là CHÍNH XÁC "true" hoặc là "false" (PHẢI là chữ thường).

Chuỗi json không hợp lệ được chuyển vào các hàm dưới đây S throw ném một ngoại lệ.


Câu trả lời gốc:

Làm thế nào về?

JSON.parse("true");

hoặc với jQuery

$.parseJSON("true");

518



Vấn đề với điều này là nhiều giá trị tiềm năng tạo ra một lỗi phân tích cú pháp dừng JS thực thi. Vì vậy, chạy JSON.parse ("FALSE") bom Javascript. Điểm của câu hỏi, tôi nghĩ, không chỉ đơn giản là giải quyết những trường hợp chính xác này, mà còn phải kiên cường với các trường hợp khác. - BishopZ
Nó khá đơn giản để nói JSON.parse("TRUE".toLowerCase()) để nó có thể phân tích cú pháp chính xác. - Yuck
@Ebenezar tại sao chúng ta quan tâm đến ie7? Nó có ~ 1% thị phần trên toàn thế giới. - Todd
@Ebenezar Tôi có thể tôn trọng điều đó, nhưng thời gian của tôi là dành tối ưu hóa cho khác> 99%. Folks sử dụng ie7 trong 15 rõ ràng là không phải là rất tốt quan tâm đến điều internet. cổ vũ. - Todd
tại sao có rất nhiều upvotes? Điều này không hiệu quả và khủng khiếp. Tiếp theo là gì? '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



Trên thực tế nó có thể được đơn giản hóa. 1) Không cần kiểm tra "true", "yes" và "1". 2) toLowerCase không trở lại null. 3) Boolean(string) giống như string!=="" đây. => switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;} - Robert
@ Robert, đẹp nhất, nhưng tôi thà có mặc định là false thay thế. - drigoangelo
@drigoangelo Having default: return true; chắc chắn là có thể. Nhưng nó sẽ thay đổi hành vi của hàm. - Robert
Tôi nghĩ đây là câu trả lời hay nhất, và muốn xây dựng nó ở đây: stackoverflow.com/questions/263965/… - BrDaHa
nếu bạn đang chuẩn hóa dữ liệu bằng cách gọi. toLowerCase (), thì bạn có thể muốn ném trong trim () để dải trắng cũng như - jCuga


Tôi nghĩ điều này phổ biến nhiều:

if (String(a) == "true") ...

Nó đi:

String(true) == "true"     //returns true
String(false) == "true"    //returns false
String("true") == "true"   //returns true
String("false") == "true"  //returns false

120



Khi bạn có thể nhận chuỗi bằng chữ hoa hoặc chữ boolean, thì String(a).toLowerCase() === 'true' - pauloya
@PauloManuelSantos cái này thực sự là một lớp lót tốt nhất ở đây :) tuyệt vời! - Adam Lukaszczyk
String("what about input like this that isn't a bool?") == "true" - Thomas Eding
@ThomasEding sai ... bạn muốn nó quay trở lại cái gì? - Snowburnt
thậm chí có thể rút ngắn bằng cách không sử dụng String() constructor: true+'' === 'true' // true - Todd


Bạn có thể sử dụng cụm từ thông dụng:

/*
 * 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);
}

Nếu bạn thích mở rộng lớp String bạn có thể làm:

String.prototype.bool = function() {
    return strToBool(this);
};

alert("true".bool());

Đối với những người (xem các ý kiến) mà muốn mở rộng đối tượng String để có được điều này nhưng đang lo lắng về enumerability và đang lo lắng về việc xung đột với mã khác mở rộng đối tượng String:

Object.defineProperty(String.prototype, "com_example_bool", {
    get : function() {
        return (/^(true|1)$/i).test(this);
    }
});
alert("true".com_example_bool);

(Sẽ không hoạt động trong các trình duyệt cũ hơn và Firefox hiển thị sai trong khi Opera, Chrome, Safari và IE hiển thị đúng. Lỗi 720760)


105



Không phải là một ý tưởng tốt để sửa đổi nguyên mẫu của các đối tượng tích hợp! - DTrejo
Bạn luôn có thể thêm tiền tố vào hàm nếu bạn sợ rằng nó sẽ can thiệp vào một số mã khác. Nếu một số mã vẫn bị hỏng, mã đó chỉ quá giòn và phải được sửa. Nếu hàm được thêm của bạn làm cho đối tượng quá nặng nơi nó gây ra vấn đề về hiệu suất cho mã khác, thì rõ ràng bạn không muốn làm điều đó. Nhưng, tôi không nghĩ rằng nó thường là một ý tưởng tồi để mở rộng các đối tượng tích hợp. Họ cũng sẽ không được công khai mở rộng nếu đó là trường hợp. - Shadow2531
Bạn không nên sửa đổi nguyên mẫu - Szymon Wygnański
@DTrejo @Szymon Tôi không đồng ý. Đây chính xác là thứ quá tải mẫu thử nghiệm. Nếu bạn sợ nó phá vỡ (nghèo) mã dựa trên for..in, có nhiều cách để ẩn các thuộc tính từ liệt kê. Xem Object.defineProperty. - devios1
Phân tích cú pháp Boolean không thuộc về lớp String .. bạn sẽ kết thúc với bất kỳ số lượng phân tích cú pháp rác và chuyển đổi ở đó. -1 để thay đổi nguyên mẫu nói chung. -1 cho các giải pháp không hoạt động trên trình duyệt chéo. -1 cho thiết kế kém. - Thomas W


Nhớ khớp với trường hợp:

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

Ngoài ra, nếu đó là hộp kiểm phần tử biểu mẫu, bạn cũng có thể phát hiện xem hộp kiểm có được chọn hay không:

var isTrueSet = document.myForm.IS_TRUE.checked;

Giả sử rằng nếu nó được kiểm tra, nó được "thiết lập" bằng true. Điều này đánh giá là true / false.


103



tại sao bạn sẽ làm một ternary? bạn đã có một boolean ở đó - nickf
Bởi vì bạn có thể? Bạn có ý gì bởi "bạn đã có một boolean ở đó"? - Jared Farrish
Jared, các === đã là một điều kiện boolean, ternary là dư thừa. - FlySwat
Thật. Tôi ghét ternaries. Vâng, tôi nghĩ rằng tôi là đúng trên toLowerCase, vì vậy tôi đã chỉnh sửa nó để loại bỏ ternary. - Jared Farrish
Điều này sẽ ném một ngoại lệ nếu myValue hoá ra là null, true hoặc một số loại khác ... - mik01aj


Gỗ mắt cẩn thận. Sau khi nhìn thấy hậu quả sau khi áp dụng câu trả lời hàng đầu với hơn 500 phiếu bầu, tôi cảm thấy bắt buộc phải đăng nội dung nào đó thực sự hữu ích:

Hãy bắt đầu với cách ngắn nhất nhưng rất nghiêm ngặt:

var str = "true";
var mybool = JSON.parse(str);

Và kết thúc với một cách thích hợp, khoan dung hơn:

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;
}

Thử nghiệm:

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



Chỉ cần nhớ rằng các trình duyệt cũ hơn có thể cần một polyfill JSON nếu bạn sử dụng phương thức đầu tiên. - DRaehal
Tốc độ truyền chuỗi "false" nhanh đến mức nào false giá trị boolean với JSON.parse? Xét về CPU, hiệu suất bộ nhớ - Green


Giải pháp của bạn là tốt.

Sử dụng === sẽ chỉ là ngớ ngẩn trong trường hợp này, như trường value sẽ luôn là String.


29



Đây là câu trả lời hợp lý duy nhất ở đây :) - Bobby Jack
Tại sao bạn nghĩ rằng nó sẽ là ngớ ngẩn để sử dụng ===? Xét về hiệu suất, nó sẽ giống hệt nhau nếu cả hai loại là Strings. Dù sao, tôi thích sử dụng hơn === vì tôi luôn tránh sử dụng == và !=. Giải thích: stackoverflow.com/questions/359494/… - Mariano Desanze
Vì value sẽ luôn là string cũng không == cũng không === là ngớ ngẩn. Cả hai đều là công cụ thích hợp cho công việc này. Chúng chỉ khác nhau khi các loại không phải công bằng. Trong trường hợp đó === chỉ đơn giản là trả về false trong khi == thực hiện một thuật toán ép buộc kiểu phức tạp trước khi so sánh. - Robert


Giải pháp phổ quát với phân tích cú pháp 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

CẬP NHẬT (không có JSON):

function getBool(val){ 
    var num = +val;
    return !isNaN(num) ? !!num : !!String(val).toLowerCase().replace(!!0,'');
}

Tôi cũng tạo ra fiddle để kiểm tra nó http://jsfiddle.net/remunda/2GRhG/


24



JSON không được hỗ trợ trong tất cả các trình duyệt: / - Aamir Afridi
ok, tôi đã thêm chức năng hoạt động khá tốt mà không cần JSON :) - Jan Remunda
Phiên bản 'không có JSON' có một số lỗi: val = "0"; console.log (!! (+ val || String (val) .toLowerCase (). thay thế (!! 0, ''))); tạo ra sự thật - Etienne
Được rồi cảm ơn. Tôi sửa chữa nó và tạo ra fiddle jsfiddle.net/remunda/2GRhG - Jan Remunda
getBool(undefined) sẽ sụp đổ Khi sử dụng phiên bản JSON gốc và sẽ trả về true cho phiên bản thứ 2. Đây là phiên bản thứ 3 trả về false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! num: !! Chuỗi (val) .toLowerCase (). thay thế (!! 0, '')); } - Ron Martinez


Tôi nghĩ rằng câu trả lời của @Steven là tốt nhất, và đã chăm sóc nhiều trường hợp hơn nếu giá trị đến chỉ là một chuỗi. Tôi muốn mở rộng nó một chút và cung cấp những điều sau đây:

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;
    }
}

Nó không cần thiết để bao gồm tất cả false trường hợp nếu bạn đã biết tất cả true các trường hợp bạn phải tính đến. Bạn có thể chuyển bất kỳ thứ gì vào phương thức này có thể chuyển cho true giá trị (hoặc thêm những người khác, nó khá đơn giản), và mọi thứ khác sẽ được xem xét false


23



Tôi sử dụng cái này vì nó bao gồm những thứ bạn nhận được từ các thuộc tính XMLN HTML ElementNodes như autocomplete="on" - philk
Tôi sẽ thêm .trim () trước toLowerCase () - Luis Lobo Borobia


var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) { 
    return !falsy.test(val) && !!val;
};

Điều này trả về false cho mọi giá trị giả và true cho mọi giá trị trung thực ngoại trừ 'false', 'f', 'no', 'n''0' (trường hợp không nhạy cảm).

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

21