javascript - วิธีการแปลงอ็อบเจ็กต์ของประเภท Map เป็นสตริง
class test{
name : string
children : Map<string,string> =new Map()
constructor(){
this.name='KIANA'
this.children.set('name','OTTO')
}
}
var t = new test()
console.log(t)
console.log(JSON.stringify(t))
ผลลัพธ์คือ:
test { children: Map { 'name' => 'OTTO' }, name: 'KIANA' }
{"children":{},"name":"KIANA"}
ฉันจะสามารถได้ข้อมูลทั้งหมดแบบนี้ได้อย่างไร:
{"children":{'name':'OTTO'},"name":"KIANA"}
หรือ
{"children":['name':'OTTO'],"name":"KIANA"}
หรือว่ามันมีวิธีที่ง่ายกว่าที่จะอธิบายความสัมพันธ์ของ 'คีย์และค่า' ใน JSON และ TypeScript
คำตอบ #1
คำนำ: ชื่อคลาสควรเริ่มด้วยตัวอักษรใหญ่ ดังนั้นฉันจึงเปลี่ยน test เป็น Test ด้านล่างนี้
เนื่องจาก Map ไม่สามารถแปลงเป็นสตริงได้โดยค่าเริ่มต้น คุณมีตัวเลือกอย่างน้อยสามข้อ:
ใช้งาน
toJSONบนคลาสTestของคุณและคืนค่าอ็อบเจ็กต์ที่มีตัวแทนสำหรับchildren(น่าจะเป็นอาเรย์ของอาเรย์) หรือสร้างซับคลาสของ
Mapที่มีtoJSONและใช้สิ่งนั้นในTestสร้าง replacer ที่คุณใช้กับ
JSON.stringifyที่จัดการกับอินสแตนซ์Map.
แม้ว่าวิธี #1 จะใช้ได้ แต่ก็หมายความว่าคุณต้องแก้ไขเมธอด toJSON ของคุณทุกครั้งที่คุณเพิ่มหรือลบคุณสมบัติจาก Test ซึ่งดูเหมือนจะเป็นปัญหาในการบำรุงรักษา:
class Test {
name: string
children: Map<string, string> = new Map()
constructor() {
this.name = 'KIANA'
this.children.set('name', 'OTTO')
}
toJSON() {
return {
name: this.name,
children: [...this.children.entries()]
}
}
}
var t = new Test()
console.log(JSON.stringify(t))
ตัวอย่างสด:
class Test {
name/*: string*/
children/*: Map<string, string>*/ = new Map()
constructor() {
this.name = 'KIANA'
this.children.set('name', 'OTTO')
}
toJSON() {
return {
name: this.name,
children: [...this.children.entries()]
}
}
}
var t = new Test()
console.log(JSON.stringify(t))[...this.children.entries()] สร้างอาเรย์ของอาเรย์ [name, value] สำหรับแมป
แต่ฉันชอบ #2 ซึ่งเป็น Map ที่เข้ากันได้กับ JSON:
class JSONAbleMap extends Map {
toJSON() {
return [...this.entries()]
}
}
...ซึ่งคุณจะนำไปใช้ใน Test:
class Test {
name: string
children: Map<string, string> = new JSONAbleMap()
constructor() {
this.name = 'KIANA'
this.children.set('name', 'OTTO')
}
}
var t = new Test()
console.log(JSON.stringify(t))
ตัวอย่างสด:
class JSONAbleMap extends Map {
toJSON() {
return [...this.entries()]
}
}
class Test {
name/*: string*/
children/*: Map<string, string>*/ = new JSONAbleMap()
constructor() {
this.name = 'KIANA'
this.children.set('name', 'OTTO')
}
}
var t = new Test()
console.log(JSON.stringify(t))หรือ #3 ฟังก์ชันแทนที่ที่คุณใช้กับ JSON.stringify:
function mapAwareReplacer(key: string|Symbol, value: any): any {
if (value instanceof Map && typeof value.toJSON !== "function") {
return [...value.entries()]
}
return value
}
...ซึ่งคุณใช้เมื่อเรียก JSON.stringify:
console.log(JSON.stringify(t, mapAwareReplacer))
ตัวอย่างสด:
function mapAwareReplacer(key, value) {
if (value instanceof Map && typeof value.toJSON !== "function") {
return [...value.entries()]
}
return value
}
class Test {
name/*: string*/
children/*: Map<string, string>*/ = new Map()
constructor() {
this.name = 'KIANA'
this.children.set('name', 'OTTO')
}
}
var t = new Test()
console.log(JSON.stringify(t, mapAwareReplacer))