ฉันจะแปลงสตริงเป็นบูลีนใน JavaScript ได้อย่างไร


2551

ฉันสามารถแปลงสตริงที่แสดงค่าบูลีน (เช่น '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);
Mark K Cowan

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")
Andrew Luca

คำตอบ:


3478

ทำ:

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

คุณสามารถทำให้มันเข้มงวดขึ้นโดยใช้ตัวดำเนินการเอกลักษณ์ ( ===) ซึ่งไม่ได้ทำการแปลงประเภทโดยนัยเมื่อตัวแปรที่เปรียบเทียบมีประเภทต่าง ๆ แทนที่จะเป็นตัวดำเนินการความเท่าเทียมกัน ( ==)

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

ไม่ได้:

คุณควรระมัดระวังเกี่ยวกับการใช้สองวิธีนี้สำหรับความต้องการเฉพาะของคุณ:

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

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

สตริงใด ๆ ที่ไม่ใช่สตริงว่างจะประเมินค่าtrueโดยใช้สตริงเหล่านั้น แม้ว่าพวกเขาจะเป็นวิธีที่สะอาดที่สุดที่ฉันสามารถนึกถึงเกี่ยวกับการแปลงแบบบูลีน แต่ฉันคิดว่าพวกเขาไม่ใช่สิ่งที่คุณต้องการ


196
myValue === 'true';myValue == 'true';เป็นอย่างแม่นยำเทียบเท่ากับ มีประโยชน์ในการใช้ไม่เป็น===มากกว่า==ที่นี่
Tim Down

551
ฉันทำตามคำแนะนำและการใช้ของ Crockford===และ!==เมื่อใดก็ตามที่เหมาะสม
guinaps

55
ตัวอย่างเช่น "TRUE" ในตัวพิมพ์ใหญ่ทั้งหมดหรือไม่
BMiner

102
@guinaps ฉันมักจะทำตามคำแนะนำของ Crockford แต่สถานการณ์==vs. ===เป็นหนึ่งในไม่กี่แห่งที่ฉันไม่ทำ ฉันสมบูรณ์ไม่เห็นว่ามัน "มักจะ" ===ทำให้รู้สึกถึงการใช้งาน มีภาษาที่พิมพ์อย่างหลวม ๆอยู่เพราะเราไม่ต้องการที่จะสนใจประเภทนี้ ถ้าเราตรวจสอบสิ่งที่if (price >= 50)เราไม่สนใจว่ามันเริ่มเป็นสตริง ฉันพูดส่วนใหญ่เราต้องการประเภทที่จะเล่นปาหี่ ในกรณีที่หายากที่เราไม่ต้องการประเภทเล่นกล (เช่นif (price === null)) ===จากนั้นเราจะใช้ นี่คือสิ่งที่ฉันทำมานานหลายปีและฉันไม่เคยมีปัญหา
JMTyler

169
@JMTyler อาจมองเห็นโปรแกรมเมอร์บำรุงรักษาที่ตามมา ใช้ตัวดำเนินการเปรียบเทียบที่เหมาะสมเสมอ! หากคุณรู้ว่า 'ทั้งสองด้าน' แน่นอนว่า แต่ไม่ได้ใช้ === ฉันจะไม่มีความรู้นั้นเมื่อดูรหัสของคุณในภายหลัง หากรหัสของคุณถูกนำกลับมาใช้ใหม่อาจกลายเป็นฝันร้าย หากคุณต้องการประเภท 'เล่นปาหี่' ตามที่คุณพูดให้ใช้ '==' แต่ JS devs มากเกินไปจะเดินทางไปที่นี้ได้ง่ายเกินไปดีกว่าที่จะกระชับโค้ดของคุณ ฉันต้องการให้สตริง 'false' แสดงว่าบูลีน 'จริง' บ่อยแค่ไหน?
aikeru

687

คำเตือน

คำตอบนี้มรดก upvoted สูงเป็นเทคนิคที่ถูกต้อง แต่เพียงครอบคลุมสถานการณ์ที่เฉพาะเจาะจงมากเมื่อค่าสตริงของคุณอยู่ตรงหรือ"true""false"

สตริง JSON ไม่ถูกต้องผ่านเข้าสู่ฟังก์ชั่นเหล่านี้ด้านล่างจะโยนข้อยกเว้น


คำตอบเดิม:

เกี่ยวกับ?

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

หรือกับ jQuery

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

62
ปัญหานี้คือว่าค่าที่เป็นไปได้จำนวนมากสร้างข้อผิดพลาดในการแยกวิเคราะห์ซึ่งหยุดการดำเนินการ JS ดังนั้นการเรียกใช้ JSON.parse ("FALSE") จึงทำให้ Javascript ระเบิด ฉันคิดว่าประเด็นของคำถามไม่ใช่เพื่อแก้ปัญหาที่แน่นอนเหล่านี้ แต่ยังสามารถแก้ไขได้ในกรณีอื่น ๆ
BishopZ

3
@ ลุคโซลูชันนี้เป็นสิ่งที่ฉันต้องการจริงๆ เอาล่ะลองดูสิ ... ฉันต้องการแปลงเป็นบูลหากเป็นค่าบูลีนในสตริง; มิฉะนั้นเพียงใช้สตริงที่มีให้ มันใช้งานได้! ขอบคุณ
jedmao

47
มันค่อนข้างง่ายที่จะพูดJSON.parse("TRUE".toLowerCase())เพื่อให้สามารถวิเคราะห์คำศัพท์ได้อย่างถูกต้อง
Yuck

27
ทำไมมี upvotes มากมาย? นี้ไม่มีประสิทธิภาพและน่ากลัวมีอะไรต่อไป 'true'.length === 4?
Maksim Vi

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 null3) Boolean(string)เหมือนกับstring!==""ที่นี่ =>switch(string.toLowerCase()) {case "false": case "no": case "0": case "": return false; default: return true;}
Robert

15
@Robert คนดี แต่ฉันอยากจะมีค่าเริ่มต้นfalseแทน
drigoangelo

@drigoangelo มีความdefault: return true;เป็นไปได้อย่างแน่นอน แต่มันจะเปลี่ยนพฤติกรรมของฟังก์ชั่น
Robert

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'
pauloya

String("what about input like this that isn't a bool?") == "true"
Thomas Eding

6
@ThomasEding false ... คุณต้องการให้ส่งคืนอะไร
Snowburnt

2
อาจจะสั้นลงได้โดยไม่ได้ใช้String()คอนสตรัค:true+'' === 'true' // true
ทอดด์

1
BTW สำหรับ 1 หรือ 0 มันควรทำการปลอมหรือเป็นจริงด้วย
Miguel

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 แสดงผลจริงข้อผิดพลาด 720760 )


10
คุณสามารถใส่คำนำหน้าฟังก์ชั่นได้ตลอดเวลาหากคุณกลัวว่าจะรบกวนรหัสอื่น ๆ หากบางรหัสยังคงแบ่งรหัสนั้นจะเปราะเกินไปและควรได้รับการแก้ไข หากฟังก์ชั่นที่เพิ่มเข้ามาของคุณทำให้วัตถุนั้นหนักเกินไปซึ่งมันทำให้เกิดปัญหาด้านประสิทธิภาพสำหรับโค้ดอื่น ๆ แน่นอนว่าคุณไม่ต้องการทำเช่นนั้น แต่ฉันไม่คิดว่ามันเป็นความคิดที่ดีที่จะขยายวัตถุในตัว พวกเขาจะไม่สามารถขยายได้ในที่สาธารณะถ้าเป็นเช่นนั้น
Shadow2531

41
@DTrejo @Symymon ฉันไม่เห็นด้วย นี่คือสิ่งที่เกินความต้องการของต้นแบบ หากคุณกลัวว่ามันจะทำลายรหัส (แย่) ที่ต้องพึ่งพา .. ในมีวิธีซ่อนคุณสมบัติจากการแจงนับ Object.definePropertyดู
devios1

เพื่อติดตามการประชุมฉันจะเรียกมันว่าparseBool
guzart

8
การแยกวิเคราะห์บูลีนไม่ได้อยู่ในคลาส String .. คุณจะพบกับตัวแยกขยะและการแปลงจำนวนเท่าใดก็ได้ -1 ถึงการเปลี่ยนต้นแบบโดยทั่วไป -1 ถึงโซลูชันที่ไม่สามารถทำงานข้ามเบราว์เซอร์ได้ -1 สำหรับการออกแบบที่ไม่ดี
โทมัส W

1
นี่คือการเปรียบเทียบประสิทธิภาพของคำตอบทั้งหมด stackoverflow.com/a/28588344/2824333
sospedra

50

ไม้ตาระวัง หลังจากเห็นผลที่ตามมาหลังจากใช้คำตอบสูงสุดกับ 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]));}

เพียงจำไว้ว่าเบราว์เซอร์รุ่นเก่าอาจต้องใช้ JSON polyfill หากคุณใช้วิธีแรก
DRaehal

1
วิธีที่รวดเร็วคือการโยนสตริง "เท็จ" เพื่อfalseค่าบูลีนด้วยJSON.parse? ในแง่ของ CPU ประสิทธิภาพของหน่วยความจำ
Green

มันจะง่ายกว่าไหมถ้าเริ่มต้นด้วย (str) {... } เพื่อกำจัดสิ่งที่ผิดพลาดไปแล้ว? และในกรณีนี้หากคุณเพียงแค่ต้องกังวลเกี่ยวกับการกลับมาจริงเพราะคุณจบลงด้วยการกลับเท็จ!
Larphoid

โปรดทราบว่าคุณสามารถลดจำนวนการทดสอบสตริงด้วย (["จริง", "ใช่", "1"]. indexOf (str.toLowerCase (). trim ()) trim =) และใช้ทางเลือกของ Boolean (str) ครอบคลุมสิ่งต่าง ๆ เช่น 'null'
Scott

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 ()
Luis Lobo Borobia

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
รุ่น 'without JSON' มีข้อบกพร่องบางอย่าง: val = "0"; console.log (!! (+ val | | String (val) .toLowerCase (). แทนที่ (!! 0, ''))); ผลิตจริง
Etienne

3
getBool(undefined)จะผิดพลาดเมื่อใช้รุ่น JSON ดั้งเดิมและจะกลับมาจริงสำหรับรุ่นที่ 2 นี่คือเวอร์ชันที่ 3 ซึ่งคืนค่า false: function getBool (val) {var num; return val! = null && (! isNaN (num = + val)? !! NUM: !! String (val) .toLowerCase (). แทนที่ (!! 0, '')); }
Ron Martinez

31

ทางออกของคุณดี

ใช้===เพียงแค่จะโง่ในกรณีนี้เป็นของสนามจะเป็นvalueString


17
ทำไมคุณคิดว่ามันน่าใช้===? ในแง่ของประสิทธิภาพมันจะเหมือนกันถ้าทั้งสองประเภทเป็น Strings อย่างไรก็ตามผมค่อนข้างใช้===ตั้งแต่ฉันมักจะหลีกเลี่ยงการใช้ของและ== !=เหตุผล: stackoverflow.com/questions/359494/…
Mariano Desanze

3
เนื่องจากvalueมักจะเป็นstringค่า==มิได้===โง่ ทั้งสองเป็นเครื่องมือที่เหมาะสมสำหรับงานนี้ พวกเขาแตกต่างกันเมื่อประเภทไม่เท่ากัน ในกรณีดังกล่าว===จะคืนค่าfalseในขณะที่==ดำเนินการอัลกอริทึมการบังคับประเภทที่ซับซ้อนก่อนการเปรียบเทียบ
Robert

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');คือคำตอบที่ดีที่สุด
thdoan

ฉันชอบที่มันรัดกุม แต่มันล้มเหลวอย่างน่าทึ่งสำหรับกรณีพื้นฐานของeval('TRUE'); พิสูจน์อีกครั้งว่าeval()เป็นความชั่วร้าย
Snowman

@Area 51 Detective Fiction ในลักษณะเดียวกันJSON.parse('TRUE')จากคำตอบด้านล่างก็ล้มเหลวอย่างน่าทึ่ง มันค่อนข้างง่ายในการบังคับเงื่อนไขข้อผิดพลาดใน JavaScript (หรือภาษาใด ๆ สำหรับเรื่องนั้น) ในการพิจารณาเรื่องนี้คุณควรทำให้สตริงเป็นปกติก่อนเช่นvar myValue = document.myForm.IS_TRUE.value.toLowerCase(); var isTrueSet = (myValue==='true' || myValue==='false') ? eval(myValue) : false;
thdoan

1
@ 10basetom: ค่อนข้างถูกต้อง คุณควรรวม.toLowerCase()ไว้ในคำตอบก็คือประเด็นของฉัน ฉันไม่ได้พยายามบังคับอะไร ตัวพิมพ์ใหญ่TRUEเป็นค่าพอที่จะส่งคืนโดยวิดเจ็ต UI จำนวนมาก
Snowman

17

สิ่งนี้ถูกนำมาจากคำตอบที่ยอมรับ แต่จริงๆแล้วมันมีจุดอ่อนมากและฉันก็ตกใจว่ามันมีจำนวน upvotes มากเท่าไหร่ปัญหาที่คุณต้องพิจารณาถึงกรณีของสตริงเพราะมันเป็นตัวพิมพ์เล็กหรือใหญ่

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

16

ฉันใช้สิ่งต่อไปนี้:

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

ฟังก์ชั่นนี้ดำเนินการบังคับบูลีนปกติด้วยข้อยกเว้นของสตริง "เท็จ" (กรณีตาย) และ "0"


16

มีคำตอบมากมายและเป็นการยากที่จะเลือก ในกรณีของฉันฉันจัดลำดับความสำคัญการแสดงเมื่อเลือกดังนั้นฉันจึงสร้างjsPerf นี้ที่ฉันหวังว่าจะสามารถเปิดไฟได้ที่นี่

สรุปผลลัพธ์ (ยิ่งสูงยิ่งดี):

  1. คำสั่งแบบมีเงื่อนไข : 2,826,922
  2. สลับตัวเรือนบนวัตถุบูล: 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" เพื่อทำความสะอาดได้มากยิ่งขึ้น :-)
tillda

อย่าเปลี่ยนกลมลองพยายามแยกการเปลี่ยนแปลงบางทีสร้างใหม่function parseBooleanแทน
สมองเหล็ก

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

ในการแปลงทั้งสตริง ("จริง", "เท็จ") และบูลีนเป็นบูลีน

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

ฟังก์ชั่นนี้สามารถจัดการกับสตริงเช่นเดียวกับบูลีนจริง / เท็จ

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"

สิ่งนี้เป็นสิ่งที่ดี แต่ใช้ได้กับชนิดของสตริงเท่านั้น ลองจินตนาการว่านี้ต้องนำมาใช้โดยตัวแปรที่เป็นอาจจะเป็นหรือ"true" trueหากมาครั้งที่สองสิ่งนี้จะไม่ทำงาน เป็นไปได้ที่document.prototypeจะใช้สิ่งนี้ทุกที่ที่เราต้องการหรือไม่
MarceloBarbosa

มันดูหรูหรา เยี่ยมมาก! อย่างไรก็ตามฉันสังเกตเห็นว่าการโหลดตัวต้นแบบพื้นฐานมากเกินไปในแอพ JS ขนาดใหญ่ (ซึ่งจำเป็นต้องมีการทดสอบหน่วย) อาจส่งผลให้เกิดพฤติกรรมที่ไม่คาดคิด (เช่นเมื่อคุณต้องการวนซ้ำกับ "สำหรับ" ผ่านอาร์เรย์ที่มีต้นแบบมากเกินไปคุณจะได้รับ คุณสมบัติบางอย่างที่คุณไม่คาดคิด) คุณได้รับการเตือน ;)
cassi.lup

ตัวแปรของคุณที่ยอมรับบูลีนเช่นกันทำหน้าที่ StringOrElse2Bool (sob) {ถ้า (type of sob === "string") {return ["no", "false", "0", "off"] indexOf (sob.toLowerCase ())! == -1? ผิดถูก; } else {return !! sob}
bortunac

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 กล่าวว่าคุณไม่สามารถแปลงเป็นโดยตรงได้ ฉันขอแนะนำให้คุณพิจารณาอินพุตสตริงนอกเหนือจาก "ความจริง" และ "เท็จ" ที่เป็น 'ความจริง' และ 'เท็จ' หากรหัสของคุณจะถูกนำไปใช้ซ้ำ / ใช้โดยผู้อื่น นี่คือสิ่งที่ฉันใช้:

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 ที่พวกเขาต้องการเปลี่ยนจากสตริงรักษาการณ์ไปเป็นชนิดเนทีฟและทำการเปรียบเทียบที่นั่นโดยเฉพาะอย่างยิ่งที่จะทำเพียงครั้งเดียวสำหรับแต่ละค่าที่ต้องถูกแปลง โปรดจำไว้ว่าต้องจัดการสิ่งที่ต้องเกิดขึ้นหากสตริง Sentinel ไม่ใช่สคริปต์ที่รู้ (เช่นคุณกำหนดค่าเริ่มต้นเป็นจริงหรือเท็จ)

กล่าวอีกนัยหนึ่งใช่คุณต้องขึ้นอยู่กับค่าของสตริง :-)


7

คำถามของฉันเกี่ยวกับเรื่องนี้ก็คือมันมีจุดมุ่งหมายเพื่อให้บรรลุวัตถุประสงค์สามประการ:

  • ส่งคืนค่า 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);

ใช้งานได้หลายกรณีไม่ล้มเหลวเมื่อค่าเช่น {} ผ่านไปและมีความรัดกุมมาก นอกจากนี้มันจะคืนค่าเท็จเป็นค่าเริ่มต้นแทนที่จะไม่ได้กำหนดหรือส่งข้อผิดพลาดซึ่งมีประโยชน์มากขึ้นในการพัฒนา Javascript แบบหลวม ๆ ไชโยกับคำตอบอื่น ๆ ที่แนะนำ!


เพียงเพื่อกลับไปสู่วัตถุประสงค์ของคุณปัญหาเดียวที่มีทางออกที่สามและดีที่สุดของคุณคือว่ามันไม่เป็นไปตามวัตถุประสงค์ # 1 - มันจะคืนค่าจริงตามมูลค่า'true'เท่านั้น แต่ไม่ใช่สำหรับข้อมูลจริงใด ๆ เพื่อให้เป็นไปตามวัตถุประสงค์ # 1 นั้นจะกระชับกว่าโซลูชัน # 2 เพียงเล็กน้อยเท่านั้นและอ่านได้น้อยกว่ามาก
JMTyler

return /^(true|yes|1|t|y)$/i.test(str);
Kevin Boucher

7

ฉันมาสายนิดหน่อย แต่ฉันมีตัวอย่างเล็ก ๆ น้อย ๆ ที่จะทำสิ่งนี้มันเป็นสิ่งสำคัญที่จะรักษา JScripts factey / falsey / สกปรก -ทั้งหมด แต่รวมถึง"false"เป็นค่าที่ยอมรับได้สำหรับเท็จ

ฉันชอบวิธีนี้มากกว่าที่กล่าวไว้เพราะไม่ต้องพึ่งพาบุคคลที่สามในการวิเคราะห์รหัส (เช่น: eval / JSON.parse) ซึ่งเกินความคิดในใจของฉันมันสั้นพอที่จะไม่ต้องการฟังก์ชั่นยูทิลิตี้และรักษา อนุสัญญาความจริง / ความเท็จอื่น ๆ

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

หนึ่งในสายการบิน

เราก็ต้องบัญชีสำหรับสตริง "false" ตั้งแต่สตริงอื่น ๆ (รวมทั้ง "ความจริง") 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.