ไม่สามารถตั้งค่าบูลีนใน LocalStorage?


113

ฉันสังเกตเห็นว่าฉันไม่สามารถตั้งค่าบูลีนในlocalStorage?

localStorage.setItem("item1", true);
alert(localStorage.getItem("item1") + " | " + (localStorage.getItem("item1") == true));

จะแจ้งเตือนเสมอtrue | falseเมื่อฉันพยายามทดสอบlocalStorage.getItem("item1") == "true"ว่าเป็นจริง ... ฉันจะตั้งค่ารายการlocalStorageเป็นจริงได้อย่างไร?

แม้ว่าจะเป็นสตริงฉันคิดว่า===จะตรวจสอบประเภทเท่านั้น?

ดังนั้น

alert("true" == true); // should be true? 

คำตอบ:


69

การใช้งาน Storage ของ Firefoxสามารถจัดเก็บสตริงได้เท่านั้น แต่ในเดือนกันยายน 2009 W3C ได้แก้ไขแบบร่างเพื่อยอมรับข้อมูลการติดตั้งใช้งาน (ยัง) ยังไม่เสร็จสิ้น( ดูแก้ไขด้านล่าง )

ดังนั้นในกรณีของคุณบูลีนจะถูกแปลงเป็นสตริง

สำหรับสาเหตุ"true" != trueตามที่เขียนไว้ในคำอธิบายของ Equal ( ==) ใน MDC *:

หากตัวถูกดำเนินการทั้งสองไม่ใช่ประเภทเดียวกัน JavaScript จะแปลงตัวถูกดำเนินการจากนั้นใช้การเปรียบเทียบที่เข้มงวด ถ้าตัวถูกดำเนินการเป็นตัวเลขหรือบูลีนตัวถูกดำเนินการจะถูกแปลงเป็นตัวเลขถ้าเป็นไปได้ มิฉะนั้นถ้าตัวถูกดำเนินการเป็นสตริงตัวถูกดำเนินการอื่นจะถูกแปลงเป็นสตริงถ้าเป็นไปได้

โปรดทราบว่าสตริงจะถูกแปลงเป็นจำนวนแทนบูลีน เนื่องจาก"true"แปลงเป็นตัวเลขNaNแล้วมันจะไม่เท่ากับอะไรเลยจึงfalseถูกส่งกลับ

(*: สำหรับมาตรฐานจริงโปรดดู ECMA-262 §11.9.3“ The Abstract Equality Comparison Algorithm”)


แก้ไข:setItemอินเตอร์เฟซที่ได้รับการหวนกลับไปรับสายเฉพาะใน2011 1 กันยายนร่างเพื่อให้ตรงกับพฤติกรรมของการใช้งานที่มีอยู่ในขณะที่ไม่มีผู้ขายมีความสนใจในการสนับสนุนการจัดเก็บที่ไม่สตริง ดูรายละเอียดhttps://www.w3.org/Bugs/Public/show_bug.cgi?id=12111


2
หากตัวถูกดำเนินการเป็นตัวเลขหรือบูลีนตัวถูกดำเนินการจะถูกแปลงเป็นตัวเลขถ้าเป็นไปได้ - ฉันไม่รู้เลยโดยสิ้นเชิง ฉันคิดว่าถ้าอันหนึ่งเป็นสตริงอีกอันหนึ่งก็จะเป็นสตริง ไชโย (+1)
Andy E

2
@ แอนดี้ตรวจสอบบันทึกที่มีประโยชน์ในหัวข้อนี้
CMS

91

ในขณะนี้การใช้งานทั้งหมดSafari , WebKit, Chrome, FirefoxและIEกำลังเป็นไปตามมาตรฐาน WebStorage เวอร์ชันเก่าซึ่งค่าของรายการจัดเก็บข้อมูลสามารถเป็นสตริงได้เท่านั้น

เป็นตัวเลือกที่จะใช้ JSON parseและstringifyวิธีการในการเป็นอันดับและdeserializeข้อมูลที่ผมแนะนำบางเวลาที่ผ่านมาในคำถามอื่นตัวอย่างเช่น:

var value = "true";
JSON.parse(value) === true; // true

4
สิ่งนี้จะแตกหักอย่างเห็นได้ชัดหากสตริงที่ส่งผ่านvalueไม่ใช่ JSON ที่ถูกต้อง (ตัวอย่างJSON.parse("a random string"))
Adonis K. Kakoulidis

3
ทรู @AdonisK. แต่ถ้าเขาใช้ JSON.stringify เมื่อตั้งค่าทั้งหมดเขาจะสามารถยกเลิกภาระหน้าที่ในการส่งออก JSON ที่ถูกต้องไปยังไลบรารีได้ และนั่นคือห้องสมุดที่มีเสถียรภาพมาก
Colt McCormack

12

โซลูชันของฉัน:

function tytPreGetBool(pre) {
    return localStorage.getItem(pre) === 'true';
}

2
@koppor อาจจะเป็นเพราะถ้า GetItem เคยจะกลับมาบูลแล้ววิธีนี้จะให้ผลลัพธ์ที่ผิดพลาดเนื่องจากเป็นtrue == 'true' false
jox

8
.. หรือธรรมดาlocalStorage.getItem(pre)==='true'ไม่มีเหลือ
phil294

1
@koppor ทำไมถึงโหวตลดลง? เพราะคน
Ayyash

1
"? true: false" ไม่จำเป็นเนื่องจาก localStorage.getItem (pre) == 'true' ให้ผลลัพธ์บูลีนแก่คุณแล้ว
FelipeDrumond

6

สิ่งนี้เกี่ยวข้องกับคำตอบของ CMS

นี่เป็นฟังก์ชั่นเล็ก ๆ น้อย ๆ ที่ฉันใช้เพื่อจัดการส่วนการแยกวิเคราะห์ของปัญหานี้ (ฟังก์ชันนี้จะทำสิ่งที่ถูกต้องต่อไปหลังจากที่การใช้งานเบราว์เซอร์สอดคล้องกับข้อมูลจำเพาะดังนั้นไม่จำเป็นต้องจำเพื่อเปลี่ยนรหัสในภายหลัง):

function parse(type) {
   return typeof type == 'string' ? JSON.parse(type) : type;
}

1
สิ่งนี้ไม่จำเป็นเมื่อเทียบกับ JSON.parse หรือไม่? JSON.parse ("true") และ JSON.parse (true) แล้วทั้งคู่คืนค่า true ดังนั้นจะยังคงทำสิ่งที่ถูกต้องหลังจากที่เบราว์เซอร์ใช้บูลีน localstorage
bscan

3

ใช้store.js :

localStorage.setItem('isUser', true)
localStorage.getItem('isUser') === "true" //true
npm i -D store

store.get('isUser')  //true

4
แต่จำเป็นจริงๆหรือไม่ที่จะต้องรวมไลบรารีทั้งหมดไว้สำหรับงานการแปลงสตริงเป็นบูลีนง่ายๆนี้?
jayqui

1

ฉันไม่แน่ใจว่า LocalStorage สามารถบันทึกค่าบูลีนได้หรือไม่ แต่ฉันบอกคุณได้ว่าเมื่อคุณทำalert("true" == true);มันจะไม่มีวันประเมินเป็นจริงเพราะคุณกำลังเปรียบเทียบสตริงกับบูลีนโดยปริยาย นั่นคือเหตุผลที่การตั้งค่าบูลีนที่คุณใช้แทนtrue"true"


1
แล้วการแจ้งเตือน ("1" == 1) ล่ะ Javascript เป็นสิ่งที่แปลก (และไม่สอดคล้องกัน)
ผู้ใช้จ่าย

@spender: นั่นเป็นเพราะตัวถูกดำเนินการถูกส่งไปยังสตริงสำหรับการเปรียบเทียบ "1" === 1จะคืนค่าเท็จ
Andy E

@ Kenny: อ๊ะfacepalmขอบคุณสำหรับการแก้ไข :-) ฉันสับสนเพราะวิธีการบูลีนส่งไปยังสตริง
Andy E

1

evalนอกจากนี้ยังสามารถใช้อย่างระมัดระวังในบางกรณี

console.log(eval("true") === true) //true

หลีกเลี่ยงevalเนื่องจากอาจไม่ปลอดภัย JSON.parse("true")ชอบ
Fred

1

สิ่งที่ฉันมักจะทำคือบันทึกค่าใน LocalStore เป็นบูลีนจากนั้นดึงข้อมูลด้วยวิธีการแยกวิเคราะห์เพื่อให้แน่ใจว่าเบราว์เซอร์ทั้งหมด วิธีการด้านล่างของฉันได้รับการปรับแต่งสำหรับตรรกะทางธุรกิจของฉัน บางครั้งฉันอาจจัดเก็บ smth เป็น 'ไม่' และยังต้องการสิ่งfalseตอบแทน

function toBoolean(str) {
    if (typeof str === 'undefined' || str === null) {
        return false;
    } else if (typeof str === 'string') {           
        switch (str.toLowerCase()) {
        case 'false':
        case 'no':
        case '0':
        case "":
            return false;
        default:
            return true;
        }
    } else if (typeof str === 'number') {
        return str !== 0
    }
    else {return true;}
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.