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

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *