Destructure ใน JavaScript คือ เครื่องหมาย 3 จุดที่วางไว้หน้าตัวแปร เช่น …myvar เป็นการถอดโครงสร้างของตัวแปร myvar ออกมาให้กลายเป็นชิ้นย่อยๆได้ โดยสามารถนำไปใช้งานได้หลายจุด
1. การใช้งาน Destructure ตอนประกาศฟังก์ชัน
การใช้ Destructure ตอนประกาศฟังก์ชันทำให้ เปลี่ยนค่าที่ส่งมาให้กลายเป็นอะเรย์ เพราะเหมือนกับ var args ในภาษา C นั่นคือตั้งใจจะให้รับอาร์กิวเมนต์กี่ตัวก็ได้
<script type="text/babel">
function f1(...b) {
console.log(b);
}
let a = { id: 1, name: 'John', dob: '2001-01-01' }
console.log(a);
f1(a);
</script>
โค้ดนี้พอโยน a เข้าไปโดนกับ …b ตัว b จึงเป็นอะเรย์เช่นนี้

สังเกตว่าฟังก์ชันที่รับ … จะรับมาเป็นอะเรย์เสมอ
2. Pass by Copy Object
แทนที่จะใช้รูปแบบ …myvar ที่จะคลี่ออกเป็นอะเรย์ แต่ถ้าใช้ {…myvar} มันจะคลี่ออกและยุบเข้ากลายเป็นออบเจกต์ตัวใหม่ ดังนั้น {…myvar} จึงเปรียบได้เหมือนกับการก็อปปี้ออบเจกต์ด้วยเช่นกัน ตัวอย่างการใช้งานเช่น
จากเดิมที่ฟังก์ชันจะรับโดยใช้ Pass by Reference เสมอ พอใส่ { …varName } เข้าไปจะทำให้อินพุตถูกก็อปปี้เป็นออบเจกต์ตัวใหม่ ดังนั้นรูปแบบนี้จึงกลายเป็น Pass by copy ทั้งออบเจกต์ที่ส่งเข้ามา
<script type="text/babel">
function f1({...b}) {
b.dob = 'XXXX-XX-XX';
return b;
}
let a = { id: 1, name: 'John', dob: '2001-01-01' }
let c = f1(a);
console.log(`a = ${JSON.stringify(a)}`);
console.log(`c = ${JSON.stringify(c)}`);
</script>
สังเกตที่ f1 รับเป็น { …b } ผลก็คือ ส่งออบเจกต์มา จะถูกก็อปปี้เป็นตัวใหม่ การทำงานในฟังก์ชันกับออบเจกต์จึงไม่เกิดผลอะไรกับตัวต้นฉบับ

สังเกตว่าค่า a ไม่เปลี่ยนหลังจากทำงานในฟังก์ชันเพราะก็อปปี้ไปทำ
3. Destruct Property
สามารถใช้ Destructure ตอนประกาศตัวแปรชนิดออบเจกต์ได้ เพื่อถอดค่าบางค่าจากต้นฉบับ โดยไม่เอามาทั้งหมด
<script type="text/babel">
function f1({id, name}) {
console.log(`id = ${id}`);
console.log(`name = ${name}`);
return { id, name };
}
let a = { id: 1, name: 'John', dob: '2001-01-01' }
let c = f1(a);
console.log(`a = ${JSON.stringify(a)}`);
console.log(`c = ${JSON.stringify(c)}`);
</script>
ด้วยการใช้ { id, name } จะถอดเฉพาะ id กับ name ออกมาจากอินพุตออบเจกต์ และประกอบกลับเข้าไปใหม่ด้วย Object Literal Enhancement เครื่องหมายปีกกา { id, name } ทำให้ฟิลด์ dob ไม่รวมอยู่ในผลลัพธ์เช่นนี้

ผลการใช้ Destructure ดึงเฉพาะบางพร็อพเพอตีและประกอบกลับใหม่
4. การเพิ่มสมาชิกให้อะเรย์แล้วได้อะเรย์ใหม่
ถ้าเราเพิ่มรายการให้อะเรย์ด้วย array.push(item) แบบนี้จะแก้ไขที่อะเรย์ต้นฉบับ แต่ถ้าใช้ array.concat(item) แบบนี้จะได้อะเรย์ใหม่ array.concat(item) สามารถเขียนแบบ spread operator ได้เป็น [ …array, item ] ซึ่งจะดูง่ายกว่า
<script type="text/babel">
const f1 = (a, item) => {
return [...a, item];
}
let c1 = [ 'red', 'green', 'blue' ];
let c2 = f1(c1, 'pink');
console.log(`c1 = ${JSON.stringify(c1)}`);
console.log(`c2 = ${JSON.stringify(c2)}`);
</script>
จะได้ผลลัพธ์ดังนี้

การใช้ spread operator แก้ไขอะเรย์ แล้วได้อะเรย์ใหม่
5. Pass by copy Array
เราสามารถรับอาร์กิวเมนต์เป็นอะเรย์แบบก็อปปี้มาตั้งแต่แรกได้เลย ด้วย [ …array ]
<script type="text/babel">
const f1 = ([...a], item) => {
a.push(item);
return a;
}
let c1 = [ 'red', 'green', 'blue' ];
let c2 = f1(c1, 'pink');
console.log(`c1 = ${JSON.stringify(c1)}`);
console.log(`c2 = ${JSON.stringify(c2)}`);
</script>
ได้ผลลัพธ์ดังนี้

ผลลัพธ์ที่ได้จากการใช้ [ …array ] รับค่าทางอาร์กิวเมนต์
หมายเหตุ – พบว่า Babel เองก็มีบักในหนังสือใช้เวอร์ชัน 6.15.0 พบว่าไปแก้ไขอะเรย์ต้นฉบับ ต้องใช้เป็นเวอร์ชัน 6.26.0
