<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: tamemo</title>
    <description>The latest articles on DEV Community by tamemo (@tamemo).</description>
    <link>https://dev.to/tamemo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1703%2Fe848c8ac-33ca-4656-9002-be6ceb59d738.jpg</url>
      <title>DEV Community: tamemo</title>
      <link>https://dev.to/tamemo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tamemo"/>
    <language>en</language>
    <item>
      <title>UX UI Design เบื้องต้น Section 2 “เจาะลึก UX Design”</title>
      <dc:creator>Rawiya Jumruanthong</dc:creator>
      <pubDate>Thu, 07 Jan 2021 02:59:56 +0000</pubDate>
      <link>https://dev.to/tamemo/ux-ui-design-section-2-ux-design-2o4d</link>
      <guid>https://dev.to/tamemo/ux-ui-design-section-2-ux-design-2o4d</guid>
      <description>&lt;p&gt;จากใน Section ที่แล้ว เราได้รู้พื้นฐานต่างๆของ UX UI Design ไปแล้ว ใน Section นี้ เราจะมาเริ่มทำความเข้าใจ และเจาะลึกลงไปกับ UX Design ให้มากขึ้น&lt;/p&gt;




&lt;h2&gt;
  
  
  หัวข้อการเรียนรู้ UX Design
&lt;/h2&gt;

&lt;p&gt;การออกแบบประสบการณ์ เป็นจุดเริ่มต้นความสำเร็จในการออกแบบ การรับรู้เป้าหมายและการเรียนรู้จากผู้ใช้งาน ทำให้เรากำหนดทิศทางของการออกแบบได้ ซึ่งจะทำให้ผู้ใช้งานเกิดการประทับใจ เกิดความสนใจ และเกิดการพอใจในการใช้งานได้ &lt;/p&gt;

&lt;p&gt;โดยจะเรียนรู้ทั้งหมดดังนี้&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;กระบวนการ Design Thinking&lt;/li&gt;
&lt;li&gt;Empathize การเข้าอกเข้าใจผู้ใช้งาน&lt;/li&gt;
&lt;li&gt;Define การกำหนด การเลือกปัญหา ที่เราควรให้ความใส่ใจ&lt;/li&gt;
&lt;li&gt;Ideate การสร้างสรรค์ไอเดียและการคิดไอเดียเพื่อแก้ปัญหา&lt;/li&gt;
&lt;li&gt;วิธีการสร้างต้นแบบ และทดสอบต้นแบบ เพื่อนำไปสู่การสร้างผลิตภัณฑ์หรือบริการที่แท้จริง&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  UX Design มีอยู่ในทุกสิ่ง
&lt;/h2&gt;

&lt;p&gt;การที่เราจะเกิด Experience หรือประสบการณ์ได้นั้น จะเกิดจากการรับรู้ และความรู้สึก ในการรับรู้อาจจะมาจากการสัมผัส การมองเห็น การได้ยิน หรือความรู้สึกที่เกิดขึ้นภายใน และต้องควบคู่ไปกับความรู้สึกด้วย เช่น รู้สึกชอบหรือไม่ชอบ รู้มีความสุขหรือไม่มี รู้สึกดีหรือไม่ดี&lt;/p&gt;

&lt;p&gt;โดยแบ่งเป็นกรณีศึกษาได้ 2 แบบ คือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;การออกแบบบริการ&lt;/li&gt;
&lt;li&gt;การออกแบบผลิตภัณฑ์&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;สรุปคือ Experience หรือประสบการณ์ มีความหลากหลาย มีความแตกต่างกัน การออกแบบประสบการณ์จึงต้องใส่ใจการรับรู้และความรู้สึกเป็นสิ่งสำคัญ&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  แนวคิดและกระบวนการ Design Thinking
&lt;/h2&gt;

&lt;p&gt;เป็นเครื่องมือที่ได้รับความนิยมมากที่สุดในการออกแบบ UX โดย Design Thinking ถูกสร้างขึ้นโดยบริษัท IDEO เป็นกระบวนการการออกแบบผลิตภัณฑ์ ซึ่งได้รับการยอมรับจากทั่วโลก ได้รับความนิยมถึงขั้นบริษัทยักษ์ใหญ่อย่าง Google, Facebook, Apple ก็ได้นำกระบวนการนี้ไปใช้งานอย่างจริงจัง จนทำให้แนวคิดนี้แพร่หลายไปทั่วโลก&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Design Thinking เป็นกระบวนการที่เน้นความเข้าอกเข้าใจผู้ใช้งานเป็นสำคัญ&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ซึ่งประกอบไปด้วย 5 ขั้นตอนสำคัญ คือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Empathize : ความเข้าใจผู้ใช้งาน&lt;/li&gt;
&lt;li&gt;Define : การเลือกปัญหาที่เราสนใจ หรือปัญหาที่เราอยากเข้าไปแก้ไข&lt;/li&gt;
&lt;li&gt;Ideate : การคิดสร้างสรรค์เพื่อแก้ปัญหา&lt;/li&gt;
&lt;li&gt;Prototype : การสร้างต้นแบบ โดยไม่เน้นการสร้างผลิตภัณฑ์หรือบริการจริงๆ แต่จะเป็นการสร้างต้นแบบเพื่อใช้ทดลองก่อน&lt;/li&gt;
&lt;li&gt;การทดสอบ : คือการนำต้นแบบที่เราได้ไปทดสอบ &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;และเมื่อจบขั้นตอนที่ 5 แล้ว ก็จะวนลูปกลับสู่ Empathize อีกครั้ง&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ดังนั้นการทำ Design Thinking จะเป็นกระบวนการที่ทำซ้ำไปเรื่อยๆ&lt;/strong&gt; และเมื่อจบการทำ Design Thinking เราจะยิ่งเข้าใจผู้ใช้งานมากยิ่งขึ้น เข้าใจถึงปัญหา และได้ไอเดียการแก้ปัญหานั้นๆมากขึ้น&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8kGI9Kf6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-EXB8GWZYSEg/X9spoTysvzI/AAAAAAAAAOc/eJp-M_bpsH0-ImtJx757awQ2OMMwbhkdwCLcBGAsYHQ/s1200/design-thinking.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8kGI9Kf6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-EXB8GWZYSEg/X9spoTysvzI/AAAAAAAAAOc/eJp-M_bpsH0-ImtJx757awQ2OMMwbhkdwCLcBGAsYHQ/s1200/design-thinking.jpg" alt="" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Empathize การเข้าอกเข้าใจผู้ใช้งาน
&lt;/h2&gt;

&lt;p&gt;เริ่มจากการตั้งสมมติฐาน ปัญหา ข้อสงสัย หรือพฤติกรรมที่คุณสนใจ ซึ่งจะเป็นการ&lt;br&gt;
นำไปสู่กลุ่มเป้าหมาย&lt;/p&gt;

&lt;p&gt;ซึ่งการทำความเข้าใจผู้ใช้งาน จะมี 4 ประเด็นหลักๆ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;สิ่งที่ผู้ใช้คิด&lt;/li&gt;
&lt;li&gt;สิ่งที่ผู้ใช้พูด&lt;/li&gt;
&lt;li&gt;สิ่งที่ผู้ใช้รู้สึก&lt;/li&gt;
&lt;li&gt;สิ่งที่ผู้ใช้ลงมือกระทำ&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;โดยจะต้องเก็บข้อมูลโดยตรง ไม่ใช่แค่ทำแบบสอบถาม หรือเสิร์ชหาตาม Google ต้องเก็บรวบรวมข้อมูลจากผู้ใช้งานโดยตรง เช่น การสังเกต การสัมภาษณ์ หรือการให้ผู้ใช้งานได้ลงมือใช้จริง&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HtKlg2l4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-f8qbRFRhDOA/X9sriUcjonI/AAAAAAAAAO0/H7ZbCeT7i2gsaaGK9LwRnjolIjNM2wamQCLcBGAsYHQ/s2048/empathize.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HtKlg2l4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-f8qbRFRhDOA/X9sriUcjonI/AAAAAAAAAO0/H7ZbCeT7i2gsaaGK9LwRnjolIjNM2wamQCLcBGAsYHQ/s2048/empathize.jpg" alt="" width="880" height="482"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  การสัมภาษณ์และวิธีการตั้งคำถาม
&lt;/h2&gt;

&lt;p&gt;เป็นเครื่องมือที่ง่ายที่สุด ไม่ต้องลงทุนสูง แต่มีข้อจำกัด ในการจะได้ข้อมูลที่เป็นเท็จมีสูงมาก ดังนั้นจึงต้องมีเครื่องมืออื่นๆเข้ามาช่วยด้วย และต้องมุ่งเน้นเพื่อให้ได้คำตอบในเรื่องสิ่งที่ผู้ใช้พูด, สิ่งที่ผู้ใช้คิด, สิ่งที่ผู้ใช้รู้สึก และ สิ่งที่ผู้ใช้ลงมือกระทำ &lt;/p&gt;

&lt;p&gt;5 รูปแบบคำถามหลักๆที่จำเป็นจะต้องมี&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Variable&lt;/strong&gt; : เป็นคำถามที่ถามเรื่องพื้นฐานทั่วไป เช่น อายุ การศึกษา เพศ ความสนใจ เป็นคำถามพื้นฐานเพื่อยืนยันว่า ผู้ที่ให้สัมภาษณ์เป็นกลุ่มเป้าหมายของเราจริงๆ&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mental Model&lt;/strong&gt; : ถามความคิด ว่าผู้ที่ให้สัมภาษณ์มีความคิดเห็นอย่างไร มีมุมมองอย่างไร เช่น คุณมีความคิดอย่างไรกับเรื่องนี้&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Activity&lt;/strong&gt; : ถามถึงสิ่งที่ผู้ที่ให้สัมภาษณ์ลงมือกระทำ ว่าผู้ที่ให้สัมภาษณ์กระทำอย่างไร อะไรคือสิ่งที่ผู้ที่ให้สัมภาษณ์กระทำอยู่เป็นประจำ เช่น ปกติเรียนหนังสืออย่างไร &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Motivation&lt;/strong&gt; : ถามเกี่ยวกับความรู้สึก ถามเกี่ยวกับเป้าหมายของผู้ที่ให้สัมภาษณ์ เช่น ความสุขในชีวิตคุณคืออะไร&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Opportunity&lt;/strong&gt; : ถามเกี่ยวกับโอกาส โดยจะมุ่งเน้นไปที่สิ่งที่ทำให้ผู้ที่ให้สัมภาษณ์เป็นปัญหา หรือสิ่งที่ผู้ที่ให้สัมภาษณ์จะลงมือทำเพื่อหลีกเลี่ยงปัญหาเหล่านั้น เช่น อะไรเป็นปัญหามากที่สุดในการเข้าห้องเรียนของคุณ และคุณมีวิธีหลีกเลี่ยงอย่างไร&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;โดยขั้นตอนการสัมภาษณ์จะเริ่มต้นด้วยคำถามพื้นฐาน(Variabl)ก่อนเสมอ จากนั้นคำถามอีก 4 รูปแบบจะเรียงอย่างไรก็ได้ แต่ต้องปรับให้เหมาะสมกับผู้ที่ให้สัมภาษณ์ และสิ่งสำคัญคือต้องถามให้ครบทั้ง 5 รูปแบบ เพื่อที่จะได้รู้ในทุกๆด้านของผู้ที่ให้สัมภาษณ์&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  เทคนิคการสัมภาษณ์และการบันทึก
&lt;/h2&gt;

&lt;p&gt;โดยพื้นฐานจะประกอบด้วยทีมงาน 3 คน ทำหน้าที่แตกต่างกัน&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interview&lt;/strong&gt; : ทำการสัมภาษณ์ ทำหน้าที่ตั้งคำถามและสื่อสารกับผู้ให้สัมภาษณ์&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note&lt;/strong&gt; : ทำหน้าที่จดบันทึก ไม่ต้องคิดหรือวิเคราะห์ แค่จดทุกอย่างที่เป็นข้อเท็จจริง ที่ผู้ถูกสัมภาษณ์พูดออกมา&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observe&lt;/strong&gt; : ทำหน้าที่สังเกต มองพฤติกรรมของผู้ถูกสัมภาษณ์ สังเกตการกระทำ และแยกให้ออกว่าข้อมูลไหนที่พูดออกมาแล้วเป็นเรื่องจริงหรือเป็นเท็จ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;gt;หากมีผู้ให้สัมภาษณ์แค่ 2 คน คนที่ทำหน้าที่ Note ต้องคอยสังเกตพฤติกรรมด้วย และหากมีผู้สัมภาษณ์คนเดียว &lt;strong&gt;ให้มุ่งเน้นไปที่การสัมภาษณ์และการจดบันทึกเป็นหลัก&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;แรกเริ่มเราจะต้องแนะนำตัวเองและบอกถึงเป้าหมายที่จะสัมภาษณ์ก่อน เพื่อให้ผู้ถูกสัมภาษณ์ไม่เครียด และสบายใจ &lt;em&gt;โดยขั้นตอนนี้จะใช้เวลาประมาณ 3 นาที&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ให้ผู้ถูกสัมภาษณ์แนะนำตนเอง และเริ่มถามคำถาม โดยจะเป็นคำถามพื้นฐาน(Variable) &lt;em&gt;ขั้นตอนนี้จะใช้เวลาประมาณ 3 นาที&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;เริ่มถามคำถามที่อยากถาม ประเด็นที่สนใจ เพื่อเก็บข้อมูล &lt;em&gt;ขั้นตอนนี้จะใช้เวลาประมาณ 15 นาที&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ขั้นตอนสุดท้าย หากมีบางสิ่งที่อยากให้ผู้ถูกสัมภาษณ์ลงมือปฏิบัติให้ดู หรือมีแบบสอบถาม &lt;em&gt;จะใช้เวลาประมาณ 5 นาที&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;ทั้ง 4 ขั้นตอนนี้ไม่ควรเกินระยะเวลา 1 ชั่วโมง&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;สรุปคือวิธีการสัมภาษณ์ เราจะต้องมุ่งความสนใจไปในเรื่องของสิ่งที่ผู้ใช้พูด, สิ่งที่ผู้ใช้คิด, สิ่งที่ผู้ใช้รู้สึก และ สิ่งที่ผู้ใช้ลงมือกระทำ โดยเตรียมคำถามให้พร้อมและครบทั้ง 5 รูปแบบ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N8WD40DI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-VuGrHaUCKg0/X9sql3EAZqI/AAAAAAAAAOo/rSz8STsUz2YYfNeU2tABp9iapOxlF7tAwCLcBGAsYHQ/s2048/shutterstock_678279070.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N8WD40DI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-VuGrHaUCKg0/X9sql3EAZqI/AAAAAAAAAOo/rSz8STsUz2YYfNeU2tABp9iapOxlF7tAwCLcBGAsYHQ/s2048/shutterstock_678279070.jpg" alt="" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  การสังเกต
&lt;/h2&gt;

&lt;p&gt;เป็นวิธีการที่มีประสิทธิภาพมาก จากการเก็บข้อมูลของผู้ใช้ วิธีการสังเกตมี 3 แบบ&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;มองถึงรูปลักษณ์ภายนอก : สีหน้า ท่าทาง บุคลิกภาพ เป็นต้น&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;มองพฤติกรรม : สิ่งที่ทำเป็นประจำ สิ่งที่ทำอย่างเคยชิน สิ่งที่ทำอย่างปกติ&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;มองการกระทำ : โฟกัส หรือให้ความสำคัญกับพฤติกรรมบางอย่างที่เราสนใจ หรือเป็นพฤติกรรมที่เราอยากแก้ไขปัญหา&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;นอกจากนี้การสังเกตจะมีอีก 2 วิธี คือ&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;สังเกตห่างๆ หรือสังเกตจากระยะไกล : เป็นการมองพฤติกรรม หรือการกระทำจากระยะไกลๆ ดูสิ่งที่เขากระทำ หรือสิ่งที่เขาตัดสินใจ วิธีการคือเลือกบุคคลแค่บุคคลเดียว แล้วมองตลอด &lt;em&gt;อย่ามองแค่รวมๆ&lt;/em&gt; ให้โฟกัสที่คน 1 คน ต่อการสังเกต หรือโฟกัสที่จุดที่เราสนใจไปเลย ตัวอย่างเช่น เราต้องการทำ Application เกี่ยวกับระบบจ่ายเงินในร้านสะดวกซื้อ ก็ให้โฟกัสแค่พฤติกรรมการจ่ายเงินของลูกค้าที่หน้าเคาท์เตอร์ไปเลย &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;สังเกตแบบประชิดตัว : จำเป็นต้องอนุญาตจากผู้ที่เราจะสังเกตก่อน ระหว่างติดตามสามารถพูดคุยได้ เพราะนั่นจะยิ่งทำให้ได้ข้อมูลมากขึ้น&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;สรุปคือการสังเกต เป็นวิธีที่ได้ผลและได้ประสิทธิภาพที่ค่อนข้างดี แต่ทำยาก และใช้สมาธิกับการใส่ใจสูงมาก ต้องสนใจทั้งภาพรวม และรายละเอียดเล็กๆน้อยๆไปพร้อมๆกัน&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KCYuvJmx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-jGYUDSbltw4/X9ssMR21PbI/AAAAAAAAAO8/iG9IwLLL3SEWyma4SlQnpViCupOqnR_wQCLcBGAsYHQ/s2048/shutterstock_1229695522.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KCYuvJmx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-jGYUDSbltw4/X9ssMR21PbI/AAAAAAAAAO8/iG9IwLLL3SEWyma4SlQnpViCupOqnR_wQCLcBGAsYHQ/s2048/shutterstock_1229695522.jpg" alt="" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  การใช้งาน Empathy Map
&lt;/h2&gt;

&lt;p&gt;คือวิธีการรวบรวม และวิเคราะห์ข้อมูล ประกอบด้วย 4 ส่วน คือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;การพูด&lt;/strong&gt; : จะบันทึกข้อมูลทุกอย่างที่ผู้พูดได้พูดไว้ และดูว่าคำพูดไหน หรือประโยคไหนที่น่าสนใจ หรือเป็นประโยคที่พูดซ้ำๆ บ่อยๆ&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;การคิด&lt;/strong&gt; : วิเคราะห์ว่าผู้ใช้มีกระบวนการคิดอย่างไร มีความคิดเห็นอย่างไร ซึ่งสามารถดูได้จากการกระทำด้วย เราจะรู้ได้ว่าเขามีการตัดสินใจอย่างไร&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ความรู้สึก&lt;/strong&gt; : วิเคราะห์ว่าผู้ใช้รู้สึกอย่างไร พอใจหรือไม่พอใจอย่างไรบ้าง สังเกตได้จากสีหน้า น้ำเสียง และการกระทำที่แสดงออกถึงความรู้สึกของผู้ใช้ &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;การลงมือทำ&lt;/strong&gt; : บันทึกสิ่งที่ผู้ใช้จำเป็นต้องกระทำ หรือตั้งใจที่จะกระทำ โดยบันทึกและดูว่า พฤติกรรมไหนที่น่าสนใจ &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;เมื่อรวบรวมและวิเคราะห์ตามนี้ได้เสร็จ จะทำให้เห็นภาพของผู้ใช้งานได้ชัดขึ้น และเป็นรูปธรรมมากขึ้น ยิ่งมีคนให้วิเคราะห์มาก ก็ยิ่งทำให้เห็นมุมมองกว้างมากขึ้น&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oxdHGskK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-hQ6PPethMUo/X9sssJr2bvI/AAAAAAAAAPE/lB2pmBBQLJ8MV1W_X0hJMUPcrOo6ykHcwCLcBGAsYHQ/s2048/shutterstock_1364311289.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oxdHGskK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-hQ6PPethMUo/X9sssJr2bvI/AAAAAAAAAPE/lB2pmBBQLJ8MV1W_X0hJMUPcrOo6ykHcwCLcBGAsYHQ/s2048/shutterstock_1364311289.jpg" alt="" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Define
&lt;/h2&gt;

&lt;p&gt;คือการกำหนดเป้าหมาย หรือปัญหาที่เราสนใจ โดยข้อมูลจากตอนแรกที่ได้มาจากการสัมภาษณ์ หรือสังเกต โดยวิธีการที่เราจะเลือกปัยหามาอยู่ 3 แบบ คือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ปัญหาที่&lt;strong&gt;หนัก&lt;/strong&gt; : ส่งผลกระทบต่อคน, สังคม และสิ่งแวดล้อม เป็นปัญหาที่เกิดผลจริง สร้างความเสียหายจริง เช่น ปัญหาที่จอดรถในห้าง ห้างจะยังไม่แก้ไขอะไร เพราะผู้คนที่มาใช้บริการยังไม่ลดลง การแก้ปัญหาในส่วนนี้จึงยังไม่จำเป็น แต่ถ้าเกิดมันทำให้ผู้ใช้บริการลดลง แสดงว่าปัญหานี้ส่งผล และควรได้รับการแก้ไขทันที &lt;/li&gt;
&lt;li&gt;ปัญหาที่&lt;strong&gt;ใหญ่&lt;/strong&gt; : ส่งผลกระทบต่อผู้คนจำนวนมาก&lt;/li&gt;
&lt;li&gt;ปัญหาที่&lt;strong&gt;ส่งผลในระยะยาว&lt;/strong&gt; : ส่งผลต่อเนื่อง และเป็นระยะเวลายาวนาน&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;gt;สรุปคือการ Define คือการที่เราเฟ้นหาประเด็นสำคัญที่ควรค่าแก่การแก้ไข เมื่อเราเลือกปัญหาได้แล้ว เราต้องเลือกผู้ใช้ว่า เป็นใคร และจะใช้ได้อย่างไร (Persona)&lt;/p&gt;




&lt;h2&gt;
  
  
  การสร้าง Persona
&lt;/h2&gt;

&lt;p&gt;คือการสร้างหรือกำหนดตัวผู้ใช้ขึ้นมา โดยจะเป็นการสร้างตัวละครสมมติขึ้นมาเพื่อเป็นตัวแทนของกลุ่มเป้าหมาย&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XujUbZap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-7eqHWdmSzsg/X0XVQNJANFI/AAAAAAAAAMk/yVyPEJF_kA8DCeQI-9yvc9PBdbffpoI3QCLcBGAsYHQ/s2000/Persona.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XujUbZap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-7eqHWdmSzsg/X0XVQNJANFI/AAAAAAAAAMk/yVyPEJF_kA8DCeQI-9yvc9PBdbffpoI3QCLcBGAsYHQ/s2000/Persona.jpg" alt="" width="880" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt; : ระบุชื่อ หรือตั้งชื่อขึ้นมา โดยเป็นชื่อสมมติ&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Photo&lt;/strong&gt; : ใส่รูปของผู้ใช้ หารูปโดยให้บุคลิก ลักษณะท่าทาง อยู่ในกลุ่มเป้าหมาย&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sentence&lt;/strong&gt; : บอกประโยคสั้นๆที่เป็นปัญหาของผู้ใช้&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Biography&lt;/strong&gt; : ระบุข้อมูลพื้นฐาน เช่น อายุ เพศ ส่วนสูง การศึกษา เป็นต้น&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Behavior&lt;/strong&gt; : ระบุพฤติกรรมของผู้ใช้ เช่น เป็นคนนอนตื่นสาย ชอบทานอาหารไทย ชอบเที่ยวต่างประเทศเดือนละครั้ง เป็นต้น&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pain&lt;/strong&gt; : ระบุความทุกข์ หรือปัญหาที่ผู้ใช้เจอ ที่เราต้องการไปแก้ไข&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Goal&amp;amp;Motivation&lt;/strong&gt; : ระบุเป้าหมายว่าคืออะไร ผู้ใช้อยากได้อะไร หรืออยากให้อะไรเกิดขึ้น และเมื่อแก้ไขปัญหาแล้วอยากให้ผลลัพธ์แบบไหนเกิดขึ้น ความคาดหวังคืออะไร &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ดังนั้นเมื่อเราสร้าง Persona เสร็จสิ้นแล้ว เราจะได้ตัวแทนของกลุ่มผู้ใช้จากที่ได้ทำมา เพื่อให้เห็นภาพชัดเจนยิ่งขึ้น และแจกจ่ายให้กับคนในทีม เพื่อให้เห็นภาพร่วมกัน เป็นไปในทิศทางเดียวกัน&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Ideate
&lt;/h2&gt;

&lt;p&gt;ในส่วนนี้่จะเน้นไปที่เรื่องของ&lt;strong&gt;ปริมาณ&lt;/strong&gt; ไม่ใช่คุณภาพ สิ่งที่สำคัญในการคิด Idea คือ &lt;strong&gt;จะต้องสนุก&lt;/strong&gt; มีความบ้า, มีความกล้า และมีความแปลกใหม่&lt;/p&gt;




&lt;h2&gt;
  
  
  เทคนิคการสร้างสรรค์ไอเดีย
&lt;/h2&gt;

&lt;p&gt;ก่อนเราจะเริ่มสร้างไอเดีย ควรจำไว้ว่า &lt;strong&gt;ต้องไม่กลัวความล้มเหลว และต้องไม่กลัวข้อจำกัด&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;เทคนิคที่ 1 คือ "การตั้งคำถาม"&lt;/strong&gt; : ต้องตั้งคำถามให้ดี ให้แหวก แล้วเราจะได้คำตอบที่สร้างสรรค์&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;เทคนิคที่ 2 คือ "การเชื่อมประสาน"&lt;/strong&gt; : คือการนำ 2 สิ่งที่ต่างกันมากๆ มาเชื่อมต่อกัน จะทำให้ได้สิ่งใหม่ที่สร้างสรรค์มากกว่าเดิมออกมา&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;เทคนิคที่ 3 คือ "ลองทำสิ่งแปลกใหม่"&lt;/strong&gt; : เปลี่ยนสิ่งแวดล้อมใหม่ๆ จะช่วยสร้างไอเดียแปลกใหม่&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;สรุปคือ การคิดสร้างสรรค์ คือการอกจากกรอบเดิมๆ ข้อจำกัดเดิมๆ และลองฝึกฝนด้วยการตั้งคำถาม, เชื่อมประสาน และทำสิ่งที่แปลกใหม่&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step Sketch
&lt;/h2&gt;

&lt;p&gt;มีทั้งหมด 4 ขั้นตอน ดังนี้&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 1&lt;/strong&gt; : รวบรวมข้อมูลที่ได้มาทั้งหมดที่มี ใช้เวลาประมาณ 20 นาที&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 2&lt;/strong&gt; : คิดไอเดียออกมาเป็นข้อๆ โดยไม่จำกัด เน้นปริมาณมากๆ และเลือกมา 1 ไอเดีย ที่ชอบที่สุด ใช้เวลาประมาณ 20 นาที&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 3&lt;/strong&gt; : นำ 1 ไอเดียที่ได้มา Sketch เพิ่มเป็น 8 ไอเดีย และเลือกมา 1 ไอเดียที่ชอบที่สุด ใช้เวลาประมาณ 8 นาที&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 4&lt;/strong&gt; : นำไอเดียที่ได้มา Sketch ตั้งชื่อว่าอะไร มีขั้นตอนการทำงานอย่างไร (เริ่มอย่างไร/ทำงานอย่างไร/จบอย่างไร)&lt;/p&gt;




&lt;h2&gt;
  
  
  Prototype
&lt;/h2&gt;

&lt;p&gt;วิธีการสร้างต้นแบบ เป็นต้นแบบในที่นี้ทำขึ้นเพื่อทดลอง และจะไม่นำไปใช้จริง โดยแนวคิดคือ หยาบ, เร็ว และถูก มีเป้าหมายเพื่อใช้ทดสอบการใช้งาน ให้รู้ว่าผู้ใช้รู้สึกอย่างไร, ใช้และจะเกิดอะไรขึ้น และตรงตามที่ออกแบบไว้หรือไม่&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HW_SaXBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-Xh4TXhfrcx0/X9stqQsNE3I/AAAAAAAAAPQ/wy_2I3GnlyEkFTf7PcgY8iSex-l5tqPHQCLcBGAsYHQ/s2048/shutterstock_1114480664.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HW_SaXBY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-Xh4TXhfrcx0/X9stqQsNE3I/AAAAAAAAAPQ/wy_2I3GnlyEkFTf7PcgY8iSex-l5tqPHQCLcBGAsYHQ/s2048/shutterstock_1114480664.jpg" alt="" width="880" height="563"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  เทคนิคการสร้าง Phototype
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Paper Prototype&lt;/strong&gt; : เหมาะกับการทดสอบ Application หรือ Website เป็นต้นแบบที่ง่ายที่สุด โดยจะวาดลงไปบนกระดาษ&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Desktop Prototype&lt;/strong&gt; : เหมาะกับการออกแบบบริการ หรือพื้นที่ด้านใดด้านหนึ่ง สร้างโดยใช้ของเล่น, กระดาษ หรือดินน้ำมัน (คล้ายๆกับการสร้าง Model ของสถาปัตย์)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Role-Play&lt;/strong&gt; : ใช้ตัวบุคคลมาสมมติเป็นตัวละคร ใช้เพื่อทดสอบการให้บริการ&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cardboard Prototype&lt;/strong&gt; : เหมาะกับการออกแบบผลิตภัณฑ์ โดยใช้อุปกรณ์คือ กระดาษแข็งที่นำมาขึ้นรูปเป็นอุปกรณ์ต่างๆ เพื่อลองให้ผู้ใช้ ทดลองจับต้องกับผลิตภัณฑ์&lt;/p&gt;




&lt;h2&gt;
  
  
  การวาด Wireframe สำหรับ Paper Prototype
&lt;/h2&gt;

&lt;p&gt;ซึ่ง Wireframe คือเทคนิคการร่างเส้นให้ออกมาเป็น Application หรือ Website โดยคงคอนเซ็ป "หยาบ/เร็ว/ง่าย"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MSG3Avfq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-dZmxYnQ6lF4/X0X1Xca2EjI/AAAAAAAAAMw/ArjVM4uoYZ4sLL5mb4fv_HJ6NCBoqZigACLcBGAsYHQ/s2048/shutterstock_1080156374.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MSG3Avfq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-dZmxYnQ6lF4/X0X1Xca2EjI/AAAAAAAAAMw/ArjVM4uoYZ4sLL5mb4fv_HJ6NCBoqZigACLcBGAsYHQ/s2048/shutterstock_1080156374.jpg" alt="" width="880" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เริ่มต้นการวาด Wireframe จากโจทย์หรือฟังก์ชั่นที่ต้องการทำ และต้องการทดสอบ โดยใช้ฟังก์ชั่นนั้นเป็นตัวตั้ง เริ่มต้นจากหน้าแรกก่อน ว่าโครงสร้างเป็นอย่างไร และตามด้วยปุ่มต่างๆกดแล้วไปไหน &lt;em&gt;ย้ำว่าวาดคร่าวๆ&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Test (การทดสอบ)
&lt;/h2&gt;

&lt;p&gt;หรือคือการทดลองว่าสิ่งที่เราคิด สิ่งที่เราคาดหวัง หรือไอเดียที่เราสร้างขึ้นมานั้น ตรงและให้ผลลัพธ์ตามที่เราคิดไว้หรือไม่&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"เป้าหมายของการทดสอบ : การได้ Feedback"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เมื่อได้รับ Feedback จะทำให้เราเห็นผลลัพธ์ เห็นภาพชัดเจนมากขึ้น&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ดังนั้นการทดสอบจึงสำคัญที่สุด เพราะมันจะนำเราไปสู่ข้อเท็จจริง และจะทำให้เราได้เรียนรู้มากขึ้น เข้าใจมากขึ้น&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---53mkLyk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-_QFwGpkxIFo/X9suK6k3nLI/AAAAAAAAAPY/hSgi-gHt7qAZpeg0Jvy1d6uhqiimOErAwCLcBGAsYHQ/s2048/shutterstock_714655705.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---53mkLyk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-_QFwGpkxIFo/X9suK6k3nLI/AAAAAAAAAPY/hSgi-gHt7qAZpeg0Jvy1d6uhqiimOErAwCLcBGAsYHQ/s2048/shutterstock_714655705.jpg" alt="" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  รูปแบบในการ Test
&lt;/h2&gt;

&lt;p&gt;มี 2 รูปแบบ โดยขึ้นอยู่กับเป้าหมาย &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;การทดสอบแบบหยาบ&lt;/strong&gt; : ไว้ใช้ทดสอบไอเดีย แนวคิด ความเป็นไปได้ของไอเดีย เช่นการใช้ Paper Prototype&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;การทดสอบแบบละเอียด&lt;/strong&gt; : ไว้เรียนรู้ภาพย่อยๆที่มีอยู่ เช่น รายละเอียดในการออกแบบ Font, สี, ปุ่ม หรือเมื่อผู้ใช้ใช้แล้ว จะมีพฤติกรรมอย่างไร เป้าหมายเพื่ออะไร ดูว่าผู้ใช้เข้าใจการทำงานของ App, ปุ่ม, ข้อความหรือไม่ &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  เครื่องมือที่ต้องใช้ในการ Test
&lt;/h2&gt;

&lt;p&gt;สิ่งที่ต้องเตรียม &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. สถานที่&lt;/strong&gt; : ถ้า Test แบบหยาบ จะใช้สถานที่แบบไหน ตรงไหนก็ได้ แต่ถ้า Test แบบละเอียด จำเป็นต้องใช้สถานที่มิดชิด และส่วนตัว เพื่อให้มีสมาธิมากขึ้น&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. ทีมงาน&lt;/strong&gt; : ประกอบไปด้วย&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interview : ทำหน้าที่ทดสอบ และสัมภาษณ์&lt;/li&gt;
&lt;li&gt;Observer : ทำหน้าที่สังเกตการณ์ คอยมองรายละเอียด และอารมณ์&lt;/li&gt;
&lt;li&gt;Simulator : ทำหน้าที่จำลองการทดสอบ เช่นทำเสียง Effect&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;แต่ถ้าไม่มีทีมงาน ให้สนใจแค่ข้อ 2 และ 3 ข้อ 1 ไม่จำเป็นเพราะเราอยากดูแค่พฤติกรรมของผู้ใช้&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;3. สิ่งที่ใช้ในการบันทึกการทดสอบ&lt;/strong&gt; : ประกอบไปด้วย&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;กล้อง : โฟกัสที่หน้าจอ App และใบหน้าของผู้ใช้งาน &lt;/li&gt;
&lt;li&gt;การจดบันทึก : เก็บรายละเอียดที่กล้องทำไม่ได้&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Al9qm6M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-yOC3JAYe02s/X9suvheMxqI/AAAAAAAAAPk/MMHpDAGIyH0agDEd0bVoF3ENdjoPMgVKACLcBGAsYHQ/s2048/shutterstock_1250079847.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Al9qm6M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-yOC3JAYe02s/X9suvheMxqI/AAAAAAAAAPk/MMHpDAGIyH0agDEd0bVoF3ENdjoPMgVKACLcBGAsYHQ/s2048/shutterstock_1250079847.jpg" alt="" width="880" height="587"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ขั้นตอนวิธีการ Test
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 1&lt;/strong&gt; : แนะนำตัว และบอกเป้าหมายของการทดสอบ ว่าทำไปเพื่ออะไร&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 2&lt;/strong&gt; : สร้างบรรยากาศ เพื่อให้ผู้ใช้รู้สึกไม่กดดัน รู้สึกสบายๆ และบอกผู้ใช้ว่าไม่มีผลต่อเขา เป็นการทดลองผลิตภัณฑ์ หรือบริการ&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 3&lt;/strong&gt; : ให้ผู้ใช้ ได้ลองใช้งานผลิตภัณฑ์ หรือบริการ จากนั้นลอบสังเกตพฤติกรรม และสีหน้า&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 4&lt;/strong&gt; : ตั้งโจทย์ที่ผู้ผลิตอยากรู้ และให้ผู้ใช้ลองตอบ เช่น เข้าใจหรือไม่ หรืออาจจะลองกำหมดโจทย์ให้ผู้ใช้ทำ "ถ้าหากต้องการโพสรูป ต้องทำอย่างไร?" เป็นต้น&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ขั้นตอนที่ 5&lt;/strong&gt; : สอบถามความรู้สึก, ข้อคิดเห็น หรือ Feedback ของผู้ใช้&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;คำถามสำคัญคือ คุณคิดว่า App นี้ เป็น App สำหรับอะไร?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  จงทำซ้ำ
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;ทำซ้ำลูปไปเรื่อยๆ เพื่อให้ได้ผลลัพธ์ที่ดีที่สุด และเข้าใจผู้ใช้มากขึ้น!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vd8SL_LB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-wv37fXx77O8/X9c6mQmnE0I/AAAAAAAAAOM/4ezj23UcAxEW82QTjqiz03Rru1ZEwtfmwCLcBGAsYHQ/s3727/Blog_ux-ui-02_loop.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vd8SL_LB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-wv37fXx77O8/X9c6mQmnE0I/AAAAAAAAAOM/4ezj23UcAxEW82QTjqiz03Rru1ZEwtfmwCLcBGAsYHQ/s3727/Blog_ux-ui-02_loop.jpg" alt="" width="880" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Golang 101: ทำความรู้จักภาษาโกฉบับโปรแกรมเมอร์</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Fri, 01 Jan 2021 07:28:27 +0000</pubDate>
      <link>https://dev.to/tamemo/golang-101-21ko</link>
      <guid>https://dev.to/tamemo/golang-101-21ko</guid>
      <description>&lt;h1&gt;
  
  
  Golang 101: พื้นฐานโกฉบับโปรแกรมเมอร์
&lt;/h1&gt;

&lt;h3&gt;
  
  
  ภาษาโกคือ?
&lt;/h3&gt;

&lt;p&gt;ภาษา Go (หรือเรียกว่า Golang) ถูกสร้างโดย Google เป้าหมายคือภาษาสำหรับเขียนโปรแกรมแนว System Programming การเขียนโปรแกรมในฝั่ง Backend เช่นการสร้าง API Server หรือ Network Application&lt;/p&gt;

&lt;p&gt;จุดเด่นของภาษาโกคือ&lt;/p&gt;

&lt;h4&gt;
  
  
  Compiler Language
&lt;/h4&gt;

&lt;p&gt;เป็นภาษาแบบ Compiler คือมีการแปล Source Code ทั้งหมดให้กลายเป็น Executable File (ภาษาเครื่อง) ซึ่งคอมพิวเตอร์สามารถนำไปรันได้ทันที ไม่ต้องแปลคำสั่งใหม่ทุกรอบแบบภาษาแนว Script เช่น Node.js หรือ PHP ทำให้ทำงานได้เร็วส์!&lt;/p&gt;

&lt;h4&gt;
  
  
  Static Type
&lt;/h4&gt;

&lt;p&gt;โกเป็นภาษาแบบ Static-Type คือตัวแปรต้องกำหนดชนิดตั้งแต่แรก ทำให้คอมไพเลอร์ช่วยเราเช็กข้อผิดพลาดได้ตั้งแต่ตอนเขียนโปรแกรมเลย ถ้าใครเคยเขียนโปรแกรมขนาดใหญ่ด้วยภาษาแนว Dynamic-Type เช่น Python, JavaScript, PHP น่าจะรู้ความปวดหัวและบั๊กของการใช้ตัวแปรแบบไม่มีการกำหนดชนิด (ภายหลังมีการสร้าง TypeScript มาใช้แทน JavaScript, ส่วน PHP ตั้งแต่เวอร์ชัน 7 ก็ถูกเพิ่ม Type ให้ตัวแปรแล้ว ... เหลือแค่ Python นี่แหละ)&lt;/p&gt;

&lt;h4&gt;
  
  
  ลักษณะของภาษา
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;ใช้เวลาคอมไพล์น้อย ได้งานเร็ว เขียนโค้ดแล้วไม่ต้องมานั่งรอนานๆ&lt;/li&gt;
&lt;li&gt;ออกแบบมาสำหรับเขียนโปรแกรมแบบ Parallel โดยเฉพาะ&lt;/li&gt;
&lt;li&gt;Syntax ของภาษาถูกออกแบบให้ใช้งานง่ายมากๆ โดยใช้คอนเซ็ปตามฉบับของภาษา C (แต่ไม่ต้องใส่ &lt;code&gt;;&lt;/code&gt;) ไม่ค่อยมีคำสั่งพิเศษๆ ทำให้กรณีทำงานเป็นทีม แต่ละคนจะเขียนโค้ดออกมาคล้ายๆ กัน&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Garbage Collector
&lt;/h4&gt;

&lt;p&gt;ภาษาโกมีการใช้ Garbage Collector สำหรับเคลียร์ตัวแปรหรืออ็อบเจคที่ไม่ถูกใช้งานแล้วออกจากหน่วยความจำให้โดยโปรแกรมเมอร์ไม่ต้องจัดการเอง&lt;/p&gt;

&lt;p&gt;สามารถดาวน์โหลดคอมไพเลอร์ภาษาโกได้ที่ &lt;a href="https://golang.org/dl/"&gt;https://golang.org&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello Go!
&lt;/h2&gt;

&lt;p&gt;มาเริ่มเขียนโกกัน สร้างไฟล์ &lt;code&gt;main.go&lt;/code&gt; ขึ้นมาก่อน แล้วเขียนโค้ดนี้ลงไป&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello Go ~"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หลังจากนั้นสามารถสั่งรันโปรแกรมได้ด้วยคำสั่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่งเราจะได้ผลลัพธ์เป็นคำว่า &lt;strong&gt;Hello Go ~&lt;/strong&gt; ออกมา&lt;/p&gt;

&lt;p&gt;หากใครเคยเขียนภาษาตระกูล C มาก่อนน่าจะคุ้นๆ กับโค้ดชุดนี้ ภาษาโกจะเริ่มต้นทำงานที่ฟังก์ชันชื่อ &lt;code&gt;main()&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;การ print ค่าออกมาใช้คำสั่ง &lt;code&gt;Println()&lt;/code&gt; จากแพกเกจชื่อ &lt;code&gt;fmt&lt;/code&gt; ย่อมาจาก formatted I/O&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;คำสั่งสำหรับการคอมไพล์ภาษาโกยังมีอีกมาก แต่เดี๋ยวเราจะพูดถึงเรื่องนี้กันต่อในบทต่อไป ในบทนี้ขอแสดงให้ดูภาพรวมของภาษาโกก่อนนะ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Variable ตัวแปร
&lt;/h2&gt;

&lt;p&gt;ภาษาโกเป็น Static-Type ที่ต้องประกาศตัวแปรและกำหนดชนิดอย่างชัดเจนก่อนใช้เสมอ&lt;/p&gt;

&lt;p&gt;โดยจะใช้คีย์เวิร์ด &lt;code&gt;var&lt;/code&gt; ตามด้วยชื่อตัวแปร และ Type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;varname&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vartype&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Expecto Patronum!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ตำแหน่งของชนิดตัวแปรจะสลับกับภาษาตระกูล C ที่ปกติจะเอา Type ขึ้นก่อน เนื่องจากโกอยากให้ลักษณะการอ่านเป็นแบบมนุษย์ เช่น &lt;code&gt;var num int&lt;/code&gt; ก็จะอ่านได้ว่า &lt;em&gt;สร้างตัวแปร num เป็นชนิด int&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Type
&lt;/h3&gt;

&lt;p&gt;ชนิดตัวแปรในโกมีเหมือนๆ กับภาษาอื่นๆ แต่โกจะเน้นการตั้งชื่อชนิดตัวแปรโดยระบุชัดๆ ไปเลยว่าเรากำลังใช้ตัวแปรขนาดกี่ bit อยู่ (ไม่มีการแยก &lt;code&gt;int&lt;/code&gt;/&lt;code&gt;long&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;/&lt;code&gt;double&lt;/code&gt;, &lt;code&gt;char&lt;/code&gt;/&lt;code&gt;string&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;

&lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="kt"&gt;int8&lt;/span&gt;  &lt;span class="kt"&gt;int16&lt;/span&gt;  &lt;span class="kt"&gt;int32&lt;/span&gt;  &lt;span class="kt"&gt;int64&lt;/span&gt;
&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="kt"&gt;uint8&lt;/span&gt; &lt;span class="kt"&gt;uint16&lt;/span&gt; &lt;span class="kt"&gt;uint32&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="kt"&gt;uintptr&lt;/span&gt;

&lt;span class="kt"&gt;float32&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;

&lt;span class="kt"&gt;complex64&lt;/span&gt; &lt;span class="kt"&gt;complex128&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ที่สำคัญมากๆ คือสำหรับโก ชนิดตัวแปร primitive (ชนิดตัวแปรพื้นฐาน) นั้น ไม่สามารถเป็น &lt;code&gt;nil&lt;/code&gt; (หรือ &lt;code&gt;null&lt;/code&gt; ในภาษาอื่น) ดังนั้นตั้งแต่สร้างตัวแปรขึ้นมา ถ้าเราไม่ได้กำหนดค่าให้มัน มันจะมีการกำหนด default value ให้เองเลย&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Zero Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;int, uint, float&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;complex&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(0+0i)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;""&lt;/code&gt; (empty string)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bool&lt;/td&gt;
&lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;function&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nil&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="c"&gt;//x = 0, y = 0 too&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type Inference
&lt;/h3&gt;

&lt;p&gt;เป็นรูปแบบย่อสำหรับการสร้างตัวแปร โดยให้คอมไพล์เลยกำหนดไทป์ให้เราแทนจาก value ที่กำหนดไว้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ข้อสังเกตของการประกาศตัวแปรแบบนี้คือไม่ต้องใส่คำว่า &lt;code&gt;var&lt;/code&gt; แล้วนะ แค่เปลี่ยน &lt;code&gt;=&lt;/code&gt; เป็น &lt;code&gt;:=&lt;/code&gt; ก็พอ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
&lt;span class="n"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;9.75&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Expecto Patronum!"&lt;/span&gt;

&lt;span class="c"&gt;//มีค่าเท่ากับ&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;platform&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;9.75&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Expecto Patronum!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สำหรับการประกาศตัวแปรแบบ int และ float นั้นจะถูกกำหนดเป็น &lt;code&gt;int&lt;/code&gt; และ &lt;code&gt;float64&lt;/code&gt; ทันที ถ้าอยากได้ตัวแปรขนาดอื่นจะใช้การสร้างตัวแปรแบบนี้ไม่ได้ ต้องกำหนดเอง&lt;/p&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;คำสั่ง I/O ขอโกเรียกว่าลอกมาจาก C เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello Go ~"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello Go ~"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;//print with new line&lt;/span&gt;

&lt;span class="n"&gt;house&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Ravenclaw"&lt;/span&gt;
&lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v points to %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;house&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;//output: 10 points to Ravenclaw&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สำหรับ format การแสดงผลแบบมาตราฐานใช้ &lt;code&gt;%v&lt;/code&gt; สำหรับ value ทั่วไป &lt;br&gt;
แต่ก็สามารถใช้ฟอร์แมทพวก &lt;code&gt;%d&lt;/code&gt;, &lt;code&gt;%f&lt;/code&gt; เพื่อจัดรูปแบบการแสดงผลตัวเลขที่ละเอียดขึ้นได้เช่นกัน&lt;/p&gt;

&lt;p&gt;ส่วนฟอร์แมทอื่นๆ สามารถดูได้ที่ &lt;a href="https://golang.org/pkg/fmt/"&gt;https://golang.org/pkg/fmt/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  String Interpolation
&lt;/h3&gt;

&lt;p&gt;หากต้องการผสมค่าจากตัวแปรเข้ากันเป็น string สำหรับภาษาอื่นๆ ในยุคนี้ส่วนใหญ่จะใช้ &lt;code&gt;$&lt;/code&gt; ในการบอกว่าตำแหน่งนั้นเป็นตัวแปร&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var year = 2020
var month = 12
var date = 31
var s = "$year / $month / $date"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับโกไม่มีอะไรแบบนั้น แต่จะใช้ฟังก์ชัน &lt;code&gt;sprintf&lt;/code&gt; จากภาษา C (อีกแล้ว) ซึ่งทำงานคล้ายๆ กับ &lt;code&gt;printf&lt;/code&gt; แต่รีเทิร์นค่ากลับมาเป็น string แทนการปริ๊นออกมา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;2020&lt;/span&gt;
&lt;span class="n"&gt;month&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;31&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v / %v / %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Flow Control
&lt;/h2&gt;

&lt;p&gt;คำสั่งควบคุมในภาษาโกนั้นเรียบง่ายมาก คือเหมือนภาษา C แต่ไม่จำเป็นต้องเขียน &lt;code&gt;()&lt;/code&gt; ครอบตัว condition เอาไว้ (อารมณ์คล้ายๆ python และ swift)&lt;/p&gt;

&lt;p&gt;แต่ block code จะต้องใส่ &lt;code&gt;{}&lt;/code&gt; ด้วยนะ ละไม่ได้&lt;/p&gt;

&lt;h3&gt;
  
  
  if-else
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// x more than 10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// else...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  loop
&lt;/h3&gt;

&lt;p&gt;ลูปในโกมีข้อแตกต่างจากภาษา C คือมีแต่คำสั่ง &lt;code&gt;for&lt;/code&gt; ให้ใช้สำหรับลูปทุกรูปแบบ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// รูปแบบ for ธรรมดา&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// รูปแบบ while ก็ยังใช้คีย์เวิร์ด for&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// หรือไม่กำหนดอะไรเลยก็ยังได้ มีค่าเท่ากับ while true&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Aways~"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  switch
&lt;/h3&gt;

&lt;p&gt;ส่วน switch นั้นไม่ต้องเติม &lt;code&gt;break&lt;/code&gt; ที่ท้ายบล็อกแล้วนะ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;1997&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Philosopher's Stone"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;1998&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Chamber of Secrets"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;1999&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Prisoner of Azkaban"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2000&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Goblet of Fire"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2003&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order of the Phoenix"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2005&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Half-Blood Prince"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="m"&gt;2007&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deathly Hallows"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not Exist!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Array และ Slice
&lt;/h2&gt;

&lt;p&gt;สำหรับตัวแปรแบบ vector ในภาษาโกนั้นมีให้ใช้ 2 แบบคือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;array: fixed length ขนาดตายตัว ยืดหดไม่ได้&lt;/li&gt;
&lt;li&gt;slice: dynamic length ขนาดเปลี่ยนแปลงได้&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;array จะใช้สัญลักษณ์ &lt;code&gt;[n]&lt;/code&gt;  เพื่อระบุว่าต้องการกี่ช่อง (กำหนดแล้วเปลี่ยนไม่ได้)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Harry"&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ron"&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hermione"&lt;/span&gt;

&lt;span class="c"&gt;//หรือถ้าอยากกำหนดค่าไปพร้อมๆ กันเลย&lt;/span&gt;

&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Harry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ron"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hermione"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 3: ใช้หาขนาดของ array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วน slice นั้นวิธีประกาศเหมือน array ทุกอย่างแต่ไม่ต้องกำหนดขนาดลงไป&lt;/p&gt;

&lt;p&gt;ตอนแรกที่สร้าง slice จะมีขนาดเป็น &lt;code&gt;0&lt;/code&gt; ส่วนถ้าต้องการเพิ่มข้อมูลเข้าไปจะใช้คำสั่ง &lt;code&gt;append&lt;/code&gt; (ซึ่งเป็นคำสั่งแบบ immutable นะ ถ้าต้องการให้ slice ตัวเดิมเปลี่ยนค่าไปด้วย ต้องเอาตัวแปรไปรับอีกที)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Harry"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ron"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hermione"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;//หรือสำหรับสายย่อ&lt;/span&gt;

&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Harry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ron"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hermione"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;การวนลูปทั้ง array และ slice สามารถใช้ &lt;code&gt;for&lt;/code&gt; แบบธรรมดา หรือใช้คู่กับคำสั่ง &lt;code&gt;range&lt;/code&gt; เพื่อวนแบบ &lt;strong&gt;foreach&lt;/strong&gt; ก็ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Harry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ron"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hermione"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Function
&lt;/h2&gt;

&lt;p&gt;ฟังก์ชันของโกเหมือนภาษาตระกูลมีไทป์ทั่วไป โดยเราต้องกำหนดไทป์ของ parameter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Draco"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Malfoy"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;sayHi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I'm %s, %s %s."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;รวมถึงถ้าฟังก์ชันนั้นมีการรีเทิร์นค่ากลับได้ ก็ต้องกำหนดไทป์ที่ด้านหลังของฟังก์ชันเช่นกัน (ถ้าไม่กำหนดจะถือว่าเป็น void คือฟังก์ชันที่ไม่มีการรีเทิร์นค่า)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่จุดเด่นอีกอย่างของฟังก์ชันในโกคือเราสามารถรีเทิร์นค่ากลับได้หลายค่าในรูปแบบของ tuple ด้วย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"val"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;และเนื่องจากโกนั้นไม่มีแนวคิดเรื่อง try-catch (สร้าง Exception เพื่อ throw ไม่ได้) ดงนั้นฟังก์ชันไหนที่มีโอกาสเกิด Error ได้ จะนิยมตอบ Error กลับมาด้วยและเป็นเหมือนธรรมเนียมว่าฝั่ง caller จะต้องมีการเช็ก Error ด้วยทุกครั้ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"errors"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0.&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"division by zero"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// TODO: handle error&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หากเจอ error แล้วอยากให้โปรแกรมหยุดทำงาน สามารใช้คำสั่ง &lt;code&gt;panic()&lt;/code&gt; หรือ &lt;code&gt;os.Exit(1)&lt;/code&gt; ก็ได้&lt;/p&gt;

&lt;h2&gt;
  
  
  Package
&lt;/h2&gt;

&lt;p&gt;ในการเขียนโปรแกรมจริงๆ เราจำเป็นต้องจัดโค้ดให้เป็นส่วนๆ เพื่อความง่ายต่อการค้นหาและตรวจสอบ ยิ่งถ้าทำงานกันเป็นทีมแล้วไม่มีข้อตกลงอะไรกันเลย โค้ดเละแน่นอน&lt;/p&gt;

&lt;p&gt;Package เป็นหนึ่งในฟีเจอร์ที่ช่วยให้เราจัดโค้ดให้เป็นสัดเป็นส่วนได้ โดยเราสามารถแยกไฟล์ของเราออกเป็นส่วนๆ แล้วจะใช้งานส่วนไหนก็ทำการ &lt;code&gt;import&lt;/code&gt; เข้ามาใช้งานได้&lt;/p&gt;

&lt;p&gt;สมมุติว่าโปรเจคของเราหน้าตาเป็นแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
└── myProject
    ├── main.go
    └── calcucator
        └── main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ในโปรเจคนี้เรามี 2 ไฟล์ คือ &lt;code&gt;main.go&lt;/code&gt; และ &lt;code&gt;calcucator/main.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// calcucator/main.go&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ทีนี้ถ้าเราอยากเรียกใช้ฟังก์ชันที่อยู่ใน calculate เราก็ต้องโหลดมันเข้ามาซะก่อน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// main.go&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"myProject/calculator"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// คำถาม&lt;/span&gt;
    &lt;span class="c"&gt;// จะเกิดอะไรขึ้นถ้าเราเรียกใช้คำสั่ง&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ถ้าใครลองโค้ดตัวนี้แล้วจะพบว่าเราสามารถเรียกใช้คำสั่ง &lt;code&gt;calculator.Calculate()&lt;/code&gt; ได้โดยไม่มีปัญหาอะไร แต่พอเป็น &lt;code&gt;calculator.add()&lt;/code&gt; แล้วพังเลย!!&lt;/p&gt;

&lt;p&gt;มันต่างกันตรงไหน?&lt;/p&gt;

&lt;p&gt;สำหรับคนที่สังเกตเห็นว่าการตั้งชื่อฟังก์ชันมันแปลกๆ ใช่แล้ว! สิ่งที่ต่างกันคือชื่อฟังก์ชันนั่นเอง เพราะว่าโกมีการกำหนดไว้ว่า&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capitalize หรือฟังก์ชันที่ตั้งชื่อขึ้นด้วยตัวอักษาตัวใหญ่ จะถือว่าเป็น public ให้ไฟล์โกอื่นๆ เรียกไปใช้งานได้ แต่ถ้าตั้งชื่อขึ้นด้วยอักษรตัวเล็กจะถือว่าเป็น private ใช้ได้แค่ในไฟล์นั้นเท่านั้น&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เรื่องนี้จะต่างจากภาษาอื่นที่นิยมใช้ keyword เช่น &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;private&lt;/code&gt; มาระบุการเข้าถึงฟังก์ชันมากๆ ใช้แรกๆ อาจจะไม่ชินโดยเฉพาะคนที่มาจากภาษาแนว OOP ที่ชอบกำหนดว่าชื่อคลาสเท่านั้นที่จเป็น Capitalize ได้&lt;/p&gt;

&lt;h2&gt;
  
  
  Struct
&lt;/h2&gt;

&lt;p&gt;สตรัคเป็นการสร้างชนิดข้อมูลเก็บกลุ่มของตัวแปรหลายๆ ชนิดเข้าไว้ด้วยกัน สำหรับภาษาปกติ ถ้าเราต้องการ define กลุ่มของข้อมูลขึ้นมา เรามักจะใช้ class ในการสร้าง &lt;strong&gt;แต่เนื่องจากภาษา Go ไม่มี class&lt;/strong&gt;เราจึงต้องมาใช้วิธีแบบ old school นั่นคือ struct แทน&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ภาษา Go มองว่าการเขียนโปรแกรมแบบ OOP โดยเฉพาะในส่วนของ Inheritance (การสืบทอด) นั้นเป็นสิ่งที่โปรแกรมเมอร์มักใช้งานผิด หรือทำให้เกิดการใช้งานผิดได้ง่ายมากเพราะ requirement มาเปลี่ยนหลังจากเริ่มเขียนโค้ดไปแล้ว &lt;/p&gt;

&lt;p&gt;โกต้องการให้เราเขียนโค้ดแบบเรียบง่าย ตรงไปตรงมากที่สุด มันเลยตัดคุณสมบัติข้อนี้ออกไป&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;รูปแบบการสร้าง struct จะใช้คีย์เวิร์ด &lt;code&gt;type&lt;/code&gt; และ &lt;code&gt;struct&lt;/code&gt; แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;house&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หลังจากสร้าง struct ขึ้นมาแล้ว เราก็เอาไปสร้างข้อมูลตามที่กำหนดไว้ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;hermione&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Hermione Granger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;house&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Gryffindor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;luna&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Luna Lovegood"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;house&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Ravenclaw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;และเราสามารถใช้ &lt;code&gt;.&lt;/code&gt; เพื่อเข้าถึง property ของ struct ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;house&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;harry&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Harry Potter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;house&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Gryffindor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v must not go back to Hogwarts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;harry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;และเนื่องจากตามคอนเซ็ปของ struct แล้วมันไม่ใช่ class มันเลยมีได้แค่ properties แต่ไม่มี method &lt;/p&gt;

&lt;p&gt;แต่ยังก็ยังดีที่เราสามารถสร้างฟังก์ชันที่ผูกกับ struct ได้ แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;house&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;spell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Harry Potter"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expelliarmus!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Stupefy!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;harry&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Harry Potter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;house&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Gryffindor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;harry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จากตัวอย่าง เราสร้างฟังก์ชัน &lt;code&gt;spell&lt;/code&gt; แต่มีการกำหนดว่าฟังก์ชันนี้จะใช้ได้กับ struct &lt;code&gt;student&lt;/code&gt; เท่านั้น (มีการกำหนดชื่อตัวแปร &lt;code&gt;s&lt;/code&gt; แทน student เอาไว้ใช้ในส่วนของฟังก์ชันด้วย)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;สำหรับเรื่องของ struct เดี๋ยวจะมีเขียนแยกเป็นอีกบทหนึ่งเลย เพราะมีรายละเอียดค่อนข้างเยอะ&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;ก็จบไปแล้วก็พื้นฐานและภาพรวมของภาษา Go น่าจะเห็นภาพกันแล้ว&lt;/p&gt;

&lt;p&gt;คิดว่าสำหรับโปรแกรมเมอร์ที่เคยเขียนภาษาอื่นมาแล้ว เรื่อง syntax ของโกนั้นไม่น่าจะเป็นปัญหา เพราะตัวภาษาก็ออกแบบตามภาษา C อยู่แล้ว &lt;strong&gt;แต่ก็ยังมีบางอย่างที่เป็นซิกเนเจอร์ของภาษาโกซึ่งเรายังไม่ได้พูดถึงในบทนี้อยู่นะ เช่น goroutine และ channel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;สรุปแล้วก็คือ โกคล้ายๆ ภาษา C ยุคใหม่ที่เขียนง่ายขึ้นหน่อย คอมไพล์เร็วขึ้นเยอะ แต่ด้วยหลักการทำให้ภาษา simple ทุกอย่าง ในให้คนที่เคยเขียนภาษายุคโมเดิร์นอาจจะขัดใจเล็กๆ น้อยๆ ไม่ว่าจะเป็นเรื่องที่โกเป็นภาษาแนว imperative จ๋ามากๆ (แนวภาษา C ไม่ค่อยมีฟีเจอร์จากโลก OOP และ Functional เลย) แถมจำกัดวิธีการเขียนค่อยข้างเยอะ ตัวแปรถ้าประกาศมาแล้วไม่ได้ใช้งาน ก็จะคอมไพล์ไม่ผ่านอีก&lt;/p&gt;

&lt;p&gt;ในบทต่อไปเราจะเริ่มลงลึกในรายละเอียดของภาษากัน...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ชอบภาษานี้มั้ย?&lt;/p&gt;

&lt;p&gt;[ความเห็นส่วนตัว] ขอตอบว่าถ้าในแง่การทำ system programming ให้มีประสิทธิภาพคือน่าสนใจมากๆ แต่ด้าน syntax ภาษานี้ไม่ผ่าน (เทียบกับทั้งภาษา high-level เช่น JavaScript หรือภาษา low-level กว่าเช่น Rust)&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>ปี2020, จริงๆ เราไม่ต้องใช้ jQuery แล้วก็ได้นะ</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Sun, 18 Oct 2020 16:40:48 +0000</pubDate>
      <link>https://dev.to/tamemo/you-not-need-jquery-jquery-595h</link>
      <guid>https://dev.to/tamemo/you-not-need-jquery-jquery-595h</guid>
      <description>&lt;p&gt;jQuery เป็นหนึ่งใน JavaScript Library ที่โด่งดังมาก (เมื่อ 10 ปีที่แล้ว) เรียกว่าในยุคนั้นแทบจะทุกเว็บจะต้องมีการติดตั้ง jQuery เอาไว้อย่างแน่นอน&lt;/p&gt;

&lt;p&gt;แต่เมื่อยุคสมัยเปลี่ยนไป เบราเซอร์ใหม่ๆ ไม่มีปัญหาการรัน JavaScript ตั้งแต่ ES6 ขึ้นไปแล้ว การใช้งาน jQuery จึงลดน้อยลงเรื่อยๆ &lt;/p&gt;

&lt;p&gt;แต่ก็มีบางโปรเจคเหมือนกัน ที่เราต้องเข้าไปแก้โค้ดเก่าๆ ซึ่งเขียนด้วย jQuery เอาไว้ ในบทความนี้จะมาเปรียบเทียบว่าทุกวันนี้เราสามารถแปลง jQuery ให้กลายเป็น Vanilla JavaScript (JavaScript เพียวๆ แบบไม่ต้องลง lib อะไรเพิ่ม เหมือนกับการกินไอติมรสเบสิกมากๆ แบบวนิลา) ได้เลยแทบจะทุกคำสั่งที่ใช้บ่อยๆ แล้วล่ะ&lt;/p&gt;

&lt;p&gt;ในบทความนี้ก็เลยลองเอาคำสั่ง jQuery ที่ใช้บ่อยๆ มาลองเทียบดู ว่าถ้าอยากเขียนแบบนี้โดยไม่ใช้ jQuery เราจะต้องทำยังไง&lt;/p&gt;

&lt;h2&gt;
  
  
  Ajax
&lt;/h2&gt;

&lt;p&gt;ในยุค jQuery กำลังรุ่งเรือง การเรียกข้อมูลจาก API ด้วย HTTP Request หรือที่ในยุคนั้นนิยมเรียกว่า &lt;strong&gt;Ajax&lt;/strong&gt; ถ้าเขียนด้วย JavaScript แบบธรรมดาจะยากมาก&lt;/p&gt;

&lt;p&gt;การที่ jQuery มีฟังก์ชันสำหรับเรียกใช้ Ajax ง่ายๆ ด้วยเป็นหนึ่งในเหตุผลที่ทำให้มันได้รับความนิยม ถึงขนาดว่าบางครั้งโหลด jQuery ติดเข้าไปเพราะต้องการใช้ฟังก์ชัน &lt;code&gt;ajax()&lt;/code&gt; แค่นั้นเลยก็มีนะ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;dataType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่ข้อเสียของ &lt;code&gt;jQuery.ajax()&lt;/code&gt; ก็คือตอนนี้ฝั่ง vanilla มีทั้ง &lt;code&gt;fetch()&lt;/code&gt; หรือไลบรารี่อย่าง &lt;code&gt;Axios&lt;/code&gt; ให้ใช้งาน ซึ่งทั้งสองวิธีนี้ถูกสร้างมาด้วย JavaScript ยุคใหม่โดยใช้ &lt;strong&gt;Promise&lt;/strong&gt; แล้ว ไม่เหมือนกับ jQuery ที่ยังใช้สไตล์ callback function อยู่เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//fetch API&lt;/span&gt;
&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;//Axios&lt;/span&gt;
&lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;pafe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Query Elements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First Match Element
&lt;/h3&gt;

&lt;p&gt;หา element ตัวแรก&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.ele&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.ele:first&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  All Elements
&lt;/h3&gt;

&lt;p&gt;หา element ทุกตัวที่ตรงกับ selector&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.ele&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;สำหรับ jQuery แล้วการหา element แค่ 1 ตัวหรือหาทั้งหมด ผลที่ได้ไม่ต่างกันนั้นคืออ็อบเจคของ jQuery แต่สำหรับวนิลาแล้ว &lt;code&gt;querySelector&lt;/code&gt; จะให้ค่ามาเป็น Element ส่วน &lt;code&gt;querySelectorAll&lt;/code&gt; จะให้ค่าเป็น &lt;strong&gt;Array of Elements&lt;/strong&gt; นะ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Nested Element
&lt;/h3&gt;

&lt;p&gt;การหา element ภายใน element อีกทีหนึ่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Action on Elements
&lt;/h3&gt;

&lt;p&gt;สำหรับการสั่ง action อะไรบางอย่างกับ element ที่ได้มา ถ้าเลือกออกมาแค่ 1 element อันนี้ไม่ยาก&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ปัญหาจะเกิดขึ้นเมื่อเรา select all กับ element ทุกตัว ซึ่งเรื่องนี้น่าจะง่ายกว่าถ้าเราใช้ jQuery เพราะการสั่ง action ของ jQuery นั้นจะวนลูปทำให้กับ element ทุกตัวอยู่แล้ว&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="cm"&gt;/* doSomething */&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับวนิลานั้น ค่าที่ได้ออกมาเป็น Array แปลว่าถ้าเราอยากสั่งให้มันทำอะไรให้ครบทุกตัว เราจะต้องวนลูปเอาเอง&lt;/p&gt;

&lt;p&gt;เช่นสมมุติว่าเราอยาก hide ทุกอย่างที่มีคลาส &lt;strong&gt;box&lt;/strong&gt; ถ้าเป็น jQuery ก็สั่งง่ายๆ เลยคือ &lt;code&gt;.hide()&lt;/code&gt; แต่ถ้าเป็นวนิลาก็วนลูปยาวไป แล้วก็กำหนดที่ style ให้ display=none แทน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DOM Traversal
&lt;/h2&gt;

&lt;p&gt;การวิ่งขึ้นๆ ลงๆ ใน DOM (โครงสร้างชั้นของ HTML ที่อยู่ในรูปแบบของ Tree) อันนี้ไม่ต่างกันมากเท่าไหร่ แค่คำสั่งของ jQuery จะสั้น/เขียนกระชับกว่านิดหน่อย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;siblings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextElementSibling&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previousElementSibling&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ตัวที่วนิลาไม่มีคือ &lt;code&gt;siblings()&lt;/code&gt; ซึ่งเป็นคำสั่งเอาไว้เลือก Element ที่อยู่เลเวลเดียวกับเราทั้งหมด (แต่ไม่รวม Element ตัวเอง) ดังนั้นเลยต้องประยุกต์นิดหน่อยโดยวิ่งขึ้นไปที่ parent แล้วเลือก child ทุกตัวที่ไม่ใช่ตัวมันเองแทน&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Handling
&lt;/h2&gt;

&lt;p&gt;การกำหนด Event Listener แทบจะไม่ต่างกันแล้ว เพราะตอนหลังวนิลาก็คำสั่ง &lt;code&gt;addEventListener&lt;/code&gt; ให้ใช้งานแล้ว&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseenter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;off&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){})&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseenter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keyup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delegate
&lt;/h3&gt;

&lt;p&gt;การดีลีเกตคือการกำหนด Event Listener ที่ Element ชั้นนอกแทนที่จะกำหนดที่ตัวมันเองตามปกติ&lt;/p&gt;

&lt;p&gt;เช่นหากเราต้องการสร้าง Listener ที่ทำงานเมื่อกด &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; ในโครงสร้างแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราก็ไปกำหนดให้ Listener อยู่ที่ &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; แทน&lt;/p&gt;

&lt;p&gt;สาเหตุที่ต้องทำแบบนี้มักจะเกิดกับกรณีที่ &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; นั้นอาจจะโดนสร้างแบบ dynamic โดย script ส่วนอื่น ทำให้อาจจะมี li เกิดขึ้นมาใหม่ได้เรื่อยๆ การไล่สั่งให้มัน Listener ทีละครั้งๆ ไปเป็นอะไรที่จัดการยากกมา เลยไปสั่งที่ ul แทน (แล้วพอเกิด Event ก็ให้ ul ส่งไปบอก li ภายในอีกที)&lt;/p&gt;

&lt;p&gt;สำหรับวนิลาไม่มีคำสั่งให้ทำดีลีเกตได้เหมือน jQuery ดังนั้นก็ต้องประยุกต์เอาอีกแล้ว (ฮา)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.box&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
      &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Event
&lt;/h3&gt;

&lt;p&gt;อันนี้เป็นการสร้าง Event ขึ้นมาเอง .. ไม่ต่างกันมากนัก&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styling
&lt;/h2&gt;

&lt;p&gt;การเซ็ต CSS ให้กับ Element &lt;/p&gt;

&lt;p&gt;ของ jQuery จะใช้คำสั่ง &lt;code&gt;.css()&lt;/code&gt; แต่วนิลาสามารถเซ็ตลงไปได้ผ่าน properties ที่ชื่อว่า &lt;code&gt;.style&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;color&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FFF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FFF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cssText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;color: #000, background: #FFF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;บางครั้ง jQuery ก็มีฟังก์ชันที่จริงๆ เบื้องหลักก็ไปเซ็ตค่า css นั่นแหละแบบนี้ด้วยนะ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Document Ready
&lt;/h2&gt;

&lt;p&gt;ในการรันสคริป บางทีเราต้องการจะให้หน้าเพจโหลดเสร็จซะก่อน สำหรับ jQuery นั้นเราใช้คำสั่ง &lt;code&gt;ready()&lt;/code&gt; หรือส่งฟังก์ชันเข้าไปเลยก็ได้ โค้ดส่วนนี้จะทำงานเหมือน document ทั้งหมดโหลดเสร็จแล้ว&lt;/p&gt;

&lt;p&gt;สำหรับ vanilla นั้นไม่มีคำสั่งสำเร็จขนาดนั้น แต่ถ้าอยากได้ก็เขียนได้ ... แต่เอาจริงๆ ส่วนใหญ่เราจะใช้วิธีเรียกฟังก์ชันที่ท้ายๆ ของหน้าเพจมากกว่า&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; 
  &lt;span class="cm"&gt;/*...*/&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt; 
  &lt;span class="cm"&gt;/*...*/&lt;/span&gt; 
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
   &lt;span class="cm"&gt;/*...*/&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Class Properties
&lt;/h3&gt;

&lt;p&gt;สำหรับสำหรับจัดการ &lt;code&gt;class&lt;/code&gt; ซึ่งตอนนี้ฝั่ง vanilla ก็ทำได้ทั้งหมดเหมือน jQuery แล้วผ่าน properties ชื่อ &lt;code&gt;classList&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active focus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggleClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;focus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blur&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Virtual Element
&lt;/h3&gt;

&lt;p&gt;Virtual Element เป็นการสร้าง Element HTML ขึ้นมาในฝั่ง JavaScript ซึ่งสามารถเอาไปปะให้แสดงผลใน document ได้ ซึ่งหลายๆ เฟรมเวิร์คตอนนี้ก็ใช้วิธีนี้แหละ ในการควบคุมการทำงานระหว่างสคริปกับ HTML&lt;/p&gt;

&lt;p&gt;สำหรับ jQuery การสร้าง Virtual Element แค่เติม &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; ครอบชื่อแท็กลงไปก็พอแล้ว ซึ่งเราจะได้ element ออกมา สามารถเอาไปใช้งานได้เลย&lt;/p&gt;

&lt;p&gt;ทางฝั่ง vanilla ตอนนี้วิธีสร้าง Virtual Element ก็ไม่ยากล่ะ เพราะมีคำสั่ง &lt;code&gt;createElement&lt;/code&gt; ให้ใช้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DOM Manipulate
&lt;/h3&gt;

&lt;p&gt;การจัดการ DOM อันนี้เราคิดว่าคำสั่งทางฝั่ง vanilla อ่านเข้าใจง่ายกว่า&lt;/p&gt;

&lt;p&gt;คือแบ่งเป็น 2 เรื่อง การแก้ไข DOM &lt;strong&gt;ภายใน&lt;/strong&gt; กับ &lt;strong&gt;ภายนอก (replace)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innserHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนการเพิ่ม element เข้าไป ก็มี 2 คำสั่งคือเพิ่มต่อท้าย กับเพิ่มแทรกเข้าไปเป็นตัวแรก ซึ่งฝั่ง vanilla นั้นไม่มีคำสั่งเพิ่มแบบแทรกเข้าไปเป็นตัวแรก ต้องหา child ตัวแรกให้ได้ก่อน แล้วใช้ &lt;code&gt;insertBefore&lt;/code&gt; ต่ออีกที&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เรื่องการลบทิ้ง, การแทรกในตำแหน่งต่างๆ, และการ clone อันนี้ไม่ยากเท่าไหร่&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;before&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertAdjacentElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;afterend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertAdjacentElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;beforebegin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloneNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Attribute
&lt;/h3&gt;

&lt;p&gt;เรื่องการจัดการ attribute ฝั่ง jQuery จะพิเศษหน่อยตรงมี &lt;code&gt;data()&lt;/code&gt; ให้ใช้งานด้วย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeAttr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Effect
&lt;/h3&gt;

&lt;p&gt;สำหรับ jQuery นั้นมีฟังก์ชันที่ทำให้เราโชว์/ซ่อน element แบบมีอนิเมชันได้ด้วย เช่น &lt;code&gt;fadeOut&lt;/code&gt;, &lt;code&gt;fadeIn&lt;/code&gt;, &lt;code&gt;slideUp&lt;/code&gt;, &lt;code&gt;slideDown&lt;/code&gt; (ซึ่งเบื้องหลังเป็นการสั่งเปลี่ยนค่าพวกความสูงหรือ opacity ด้วยลูปเอานะ)&lt;/p&gt;

&lt;p&gt;สำหรับการเขียนแบบใหม่ ตอนนี้เราไม่นิยมให้ JavaScript เป็นคนจัดการอนิเมชันแล้ว แต่โยนไปเป็นหน้าที่ของ css แทน เช่นการใช้ transition &lt;/p&gt;

&lt;p&gt;ฝั่ง JavaScript มีหน้าที่แค่ระบุคลาสของ css เข้าไปเท่านั้นพอ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//jQuery&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fadeOut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//Vanilla&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hide&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;show&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* With this CSS */&lt;/span&gt;
&lt;span class="nc"&gt;.show&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.hide&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;400ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;จริงๆ น่าจะยังมีอีกหลายคำสั่ง&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>jquery</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Vue 3.0 มีอะไรเปลี่ยนแปลง/มีอะไรใหม่บ้าง?</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Sun, 04 Oct 2020 16:52:45 +0000</pubDate>
      <link>https://dev.to/tamemo/vue-3-0-2kbo</link>
      <guid>https://dev.to/tamemo/vue-3-0-2kbo</guid>
      <description>&lt;h2&gt;
  
  
  เขียนใหม่ด้วย TypeScript
&lt;/h2&gt;

&lt;p&gt;ภาษา JavaScript นั้นไม่มี Type ของตัวแปรทำให้เวลาเขียนโปรแกรมมีโอกาสเกิดข้อผิลพลาดเยอะ ดังนั้นการเขียนงานโปรเจคใหญ่ๆ คนเลยนิยมเปลี่ยนไปใช้ TypeScript แทน (ถ้ายังไม่รู้จัก TypeScript &lt;a href="https://www.centrilliontech.co.th/blog/2843/history-of-typescript/%5D"&gt;อ่านต่อได้ที่นี่&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;สำหรับ Vue 3.0 นี้ก็เป็นการเขียนใหม่ด้วย TypeScript แทน แต่เวลาเราเอามาใช้งาน เราสามารถเลือกได้ว่าจะใช้แบบ JavaScript ตามปกติ หรือจะใช้แบบ TypeScript ก็ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;book&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vue 3 Guide&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vue Team&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://v3.vuejs.org/guide/typescript-support.html"&gt;อ่านเรื่อง TypeScript ต่อได้ที่นี่&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  JSX
&lt;/h2&gt;

&lt;p&gt;เป็นฟีเจอร์ที่เอามาจาก React นั้นคือแทนที่จะใช้ Hyperscript แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolveComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anchored-heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Vue.h ย่อมาจาก Hyperscript ซึ่งหมายถึง script ที่เอาไว้สร้าง HTML structures นั่นเอง&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;การเขียน JSX ได้จะทำให้เราเขียน HTML ลงไปในโค้ด JavaScript ตรงๆ ได้เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AnchoredHeading&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./AnchoredHeading.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AnchoredHeading&lt;/span&gt; &lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt; world&lt;/span&gt;&lt;span class="err"&gt;!
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AnchoredHeading&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#demo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://v3.vuejs.org/guide/render-function.html#jsx"&gt;อ่านเรื่อง JSX ต่อได้ที่นี่&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  API ที่เปลี่ยนไปใน Vue 3
&lt;/h2&gt;

&lt;p&gt;ในหัวข้อนี้ขอยกตัวอย่างโค้ดข้างล่างนี่ ซึ่งรันได้ปกติใน Vue 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;my-button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;whenclick=&lt;/span&gt;&lt;span class="s"&gt;"changeTitleText"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/my-button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/vue@2.6.12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;button @click="handleClick"&amp;gt;Click Me!&amp;lt;/button&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whenclick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;นี่คือ Title แบบ Vue 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;changeTitleText&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;โค้ดนี้ทำงานได้ใน Vue 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/tanapoj/embed/gOryYXY?height=600&amp;amp;default-tab=js,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;ในตัวอย่างนี้มีการสร้าง component ชื่อ &lt;code&gt;my-button&lt;/code&gt; ขึ้นมาหนึ่งตัว แล้วตั้งค่าไว้ว่าถ้ามีการคลิก ให้เปลี่ยนข้อความ &lt;code&gt;title&lt;/code&gt; ซะ&lt;/p&gt;

&lt;p&gt;ทีนี้ ถ้าเราเปลี่ยนไปใช้ Vue 3 ตัวนี้แทน &lt;code&gt;https://unpkg.com/vue@3.0.0&lt;/code&gt; เราจะพบว่าโค้ดของเรารันไม่ได้ไปซะแล้ว&lt;/p&gt;

&lt;p&gt;สาเหตุก็เพราะว่า API การเรียกใช้งานมีการเปลี่ยนแปลง&lt;/p&gt;

&lt;h3&gt;
  
  
  วิธี createApp
&lt;/h3&gt;

&lt;p&gt;จากเดิมใน Vue 2 ถ้าเราจะสร้าง Application ขึ้นมา ก็จะใช้วิธีการ new Vue ขึ้นมาตรงๆ เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;//TODO&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับ Vue 3 จะเปลี่ยนไปใช้คำสั่ง &lt;code&gt;createApp&lt;/code&gt; แทน (ไม่สามารถสร้างเองได้แล้ว ต้องสร้างผ่าน factory function ที่ Vue เตรียมไว้ให้เท่านั้น)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//TODO&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หรือ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//TODO&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;อีกเรื่องหนึ่งคือการ mount แอพเข้ากับ html โดยใช้ &lt;code&gt;el&lt;/code&gt; นั้นโดนตัดออกไปแล้ว&lt;/p&gt;

&lt;p&gt;ไปใช้วิธีการ mount ด้วยเมธอด &lt;code&gt;.mount()&lt;/code&gt; หลังจากสร้างแอพไปแล้วแทน ซึ่งเป็นการแยกส่วนโลจิคออกจากการกำหนดส่วนแสดงผล (HTML) ออกจากกัน ทำให้ตอนนี้เราสามารถสร้างแอพเปล่าๆ โดยยังไม่ต้อง mount ได้แล้ว ถ้าอยากเอาไปทำเทสเพิ่มก็ทำได้ง่ายขึ้น&lt;/p&gt;

&lt;h3&gt;
  
  
  data ต้องเป็น method เท่านั้น
&lt;/h3&gt;

&lt;p&gt;ปกติ &lt;code&gt;data&lt;/code&gt; ของ Vue 2 นั้นสามารถกำหนดเป็น object หรือ function ที่รีเทิร์น object กลับมาแบบไหนก็ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;นี่คือ Title แบบ Vue 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับ Vue 3 ถูกกำหนดว่า &lt;code&gt;data&lt;/code&gt; จะต้องเป็น function เท่านั้น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;นี่คือ Title แบบ Vue 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Component ผูกกับ app
&lt;/h3&gt;

&lt;p&gt;ใน Vue 2 เวลาเราสร้างคอมโพเนนท์ เราจะสั่งผ่านตัวแปร Vue ที่เป็นระดับ global แปลว่าคอมโพเนนท์นี้สามารถเรียกใช้จาก Application ของ Vue ตัวไหนก็ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;button @click="handleClick"&amp;gt;Click Me!&amp;lt;/button&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whenclick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับ Vue 3 แล้วการจะสร้างคอมโพเนนท์จะต้องสร้างให้แอพตัวใดตัวหนึ่งไปเลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//TODO&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;emits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whenclick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;//optional&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;button @click="handleClick"&amp;gt;Click Me!&amp;lt;/button&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;whenclick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;emits&lt;/code&gt; เป็น properties ที่จะกำหนด หรือไม่กำหนดก็ได้ หน้าที่ของมันคือเอาไว้เก็บชื่อเมธอดทั้งหมดที่คอมฑโพเนนท์ตัวนี้ทำได้ (มันก็คือ &lt;code&gt;$emit&lt;/code&gt; อะไรได้บ้างนั่นแหละ) แต่การใส่ใน &lt;code&gt;emits&lt;/code&gt; นั้นจะทำให้เวลาเรามาอ่านว่าคอมโพเนนท์ตัวนี้มีอะไรให้เรียกใช้ได้บ้างก็จะดูจากตรงนี้ได้เลย ไม่ต้องเสียเวลาไปไล่โค้ดข้างในอีกที&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/tanapoj/embed/OJNGLEV?height=600&amp;amp;default-tab=js,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Vue Router ต้องสร้างด้วย createRouter()
&lt;/h3&gt;

&lt;p&gt;เร้าเตอร์ก็เป็นอีกตัวที่มีการเปลี่ยนรูปแบบการเขียน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueRouter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FirstPage&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/FirstPage.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/FirstPage.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VueRouter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;VueRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;routers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FirstPage&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SecondPage&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;$mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;โดยการสร้าง router จะต้องสร้างแยกตั้งหากด้วยคำสั่ง &lt;code&gt;createRouter()&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;รวมถึงโหมด history ที่ตอนแรกเป็นค่าคอนฟิก, ใน Vue 3 ก็แยกออกมาเป็น &lt;code&gt;createWebHistory()&lt;/code&gt; แล้วเหมือนกัน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createWebHistory&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;FirstPage&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/FirstPage.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/FirstPage.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;createWebHistory&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;routers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FirstPage&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/second&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SecondPage&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isReady&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Vuex ต้องสร้าง store ด้วย createStore()
&lt;/h3&gt;

&lt;p&gt;คล้ายๆ กับข้อเมื่อกี้คือถ้าในโค้ดเรามีการใช้ Vuex การจะสร้าง store ขึ้นมาแทนที่จะ new Vuex.Store ตรงๆ ก็จะเปลี่ยนไปสร้างผ่าน &lt;code&gt;createStore()&lt;/code&gt; แทน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vuex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vuex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;$mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vuex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;พวกค่าต่างๆ ของ store เช่น &lt;code&gt;state&lt;/code&gt;, &lt;code&gt;mutations&lt;/code&gt;, &lt;code&gt;getters&lt;/code&gt;, &lt;code&gt;actions&lt;/code&gt; ก็เซ็ตเหมือนเดิมทุกอย่าง ไม่มีอะไรเปลี่ยนแปลง&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;โดยรวมแล้ว Vue 3 มีการเปลี่ยน API ให้แยกส่วนกันมากขึ้น ทำให้โครงสร้างโค้ดถูกแบ่งเป็นโมดูลๆ จัดการและเทสง่ายขึ้น&lt;/p&gt;

&lt;h2&gt;
  
  
  Fragment
&lt;/h2&gt;

&lt;p&gt;สำหรับใช้ที่เคยใช้ React มาก่อน Fragment ใน Vue ก็ใช้คอนเซ็ปเดียวกันนั่นแหละ&lt;/p&gt;

&lt;p&gt;ตามปกติแล้วเวลาเราสร้าง template จำเป็นจะต้องมี root element 1 ตัวครอบทุกอย่างเอาไว้ ซึ่งหลายๆ ครั้งมันก็ไม่สะดวกเอาซะเลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Layout.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สำหรับ Vue 3 นั้นอนุญาตให้เราสร้าง root element หลายตัวใน template ได้แล้ว&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Layout.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;v-bind=&lt;/span&gt;&lt;span class="s"&gt;"$attrs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Teleport Component
&lt;/h2&gt;

&lt;p&gt;teleport เป็นฟีเจอร์ที่ทำให้คอมโพเนนท์บางส่วนที่เราสร้างขึ้นมาใน Application สามารถ "เทเลฟอร์ท" หรือ "วาร์ป" ออกไปข้างนอกได้!&lt;/p&gt;

&lt;p&gt;ตัวอย่างที่เข้าใจง่ายที่สุดน่าจะเป็น Modal หรือการที่มีกล่องเหรือเฟรมอะไรสักอย่างเด้งขึ้นมาซ้อนทับ content ของเราเป็นอีกเลเยอร์หนึ่ง&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tb_8mdTl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.dribbble.com/users/536/screenshots/11128907/media/69024e5858222d97ee3d66c7980fb621.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tb_8mdTl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.dribbble.com/users/536/screenshots/11128907/media/69024e5858222d97ee3d66c7980fb621.png" alt="" width="880" height="688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;สำหรับ Vue เวอร์ชันก่อนๆ ที่ต้องเขียนทุกอย่างอยู่ในขอบเขตของ Application เท่านั้น&lt;/p&gt;

&lt;p&gt;ถ้าเราจะสร้าง Modal ขึ้นมาก็จะต้องสร้างไว้ข้างในแอพนั้นแหละ&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DAytvBXI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-y1XVCYQxBPI/X3nhraHRqmI/AAAAAAAASrA/U5DYYp6iBKQ0hXvhPp9a4IrJ3Ptk6vt7QCNcBGAsYHQ/s1660/vue-3-change-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DAytvBXI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-y1XVCYQxBPI/X3nhraHRqmI/AAAAAAAASrA/U5DYYp6iBKQ0hXvhPp9a4IrJ3Ptk6vt7QCNcBGAsYHQ/s1660/vue-3-change-01.png" alt="" width="880" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;แต่สำหรับ Vue 3 เราสามารถกำหนดสิ่งที่เรียกว่า teleport เพื่อบอกว่าโค้ดตรงนี้นะ เราจะส่งมันออกไปแสดงผลข้างนอกแอพ!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GLj2uNQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-A2CqHSnaL3A/X3nhrgGs7XI/AAAAAAAASrE/b6Z9NnRapQQsbFrXjlJwQgrrSLBq3BBRACNcBGAsYHQ/s1651/vue-3-change-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GLj2uNQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-A2CqHSnaL3A/X3nhrgGs7XI/AAAAAAAASrE/b6Z9NnRapQQsbFrXjlJwQgrrSLBq3BBRACNcBGAsYHQ/s1651/vue-3-change-02.png" alt="" width="880" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากเดิมเป็นโค้ดแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;modal-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;button @click="modalOpen = true"&amp;gt;
        Open full screen modal!
    &amp;lt;/button&amp;gt;

    &amp;lt;div v-if="modalOpen" class="modal"&amp;gt;
      &amp;lt;div&amp;gt;
        I'm a modal! 
        &amp;lt;button @click="modalOpen = false"&amp;gt;
          Close
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;modalOpen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ให้เราเพิ่ม &lt;code&gt;&amp;lt;teleport to="body"&amp;gt;&lt;/code&gt; ลงไปครอบคอมโพเนนท์ส่วนที่ต้องการส่งออกไปข้างนอก (เช่นเคสนี้ส่งไปแสดงผลที่ชั้น body)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;modal-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;button @click="modalOpen = true"&amp;gt;
        Open full screen modal! (With teleport!)
    &amp;lt;/button&amp;gt;

    &amp;lt;teleport to="body"&amp;gt;
      &amp;lt;div v-if="modalOpen" class="modal"&amp;gt;
        &amp;lt;div&amp;gt;
          I'm a teleported modal! 
          (My parent is "body")
          &amp;lt;button @click="modalOpen = false"&amp;gt;
            Close
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/teleport&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;modalOpen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/Vue/embed/gOPNvjR?height=600&amp;amp;default-tab=js,result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;จริงๆ ยังมีอีกหลายฟีเจอร์ที่ Vue 3 มีการเพิ่มฝเปลี่ยนแปลง แต่อันนี้เลือกมาเฉพาะๆ ตัวที่คิดว่าสำคัญ&lt;/p&gt;

&lt;p&gt;ป.ล. Vue 3 นั้นออกเวอร์ชัน 3.0.0 เรียบร้อยแล้ว แต่เฟรมเวิร์คหลัๆ บางตัวก็ยังไม่เสร็จดี เช่น router หรือ Vuex และสำหรับการติดตั้งจะต้องใช้ &lt;code&gt;npm i vue@next&lt;/code&gt; หากต้องการจะใช้เวอร์ชัน 3 (ถ้าใช้ &lt;code&gt;npm i vue&lt;/code&gt; จะได้เวอร์ชัน 2) ซึ่งการเปลี่ยนแปลงให้ vue 3 เป็นตัวหลักแทนน่าจะดำเนินการเสร็จภายในสิ้นปี 2020 นี้&lt;/p&gt;

&lt;p&gt;อ่านเพิ่มเติมได้ที่ &lt;a href="https://github.com/vuejs/vue-next/releases/tag/v3.0.0"&gt;Release Note&lt;/a&gt; นะ&lt;/p&gt;

</description>
      <category>vue</category>
      <category>news</category>
    </item>
    <item>
      <title>สอนใช้ TypeScript ในโปรเจค Node.js + Express</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Sun, 27 Sep 2020 13:57:04 +0000</pubDate>
      <link>https://dev.to/tamemo/typescript-node-js-express-4e33</link>
      <guid>https://dev.to/tamemo/typescript-node-js-express-4e33</guid>
      <description>&lt;h2&gt;
  
  
  Node.js กับ TypeScript
&lt;/h2&gt;

&lt;p&gt;Node.js เป็นหนึ่งในเฟรมเวิร์คยอดนิยมสำหรับเขียนโปรแกรมฝั่ง Backend แต่เพราะมันสร้างมาตั้งแต่ปี 2009 ยุคที่ JavaScript ยังเป็นเวอร์ชัน ES5 อยู่เลย&lt;/p&gt;

&lt;p&gt;โดยดีฟอลต์แล้ว Node.js เลยไม่ซัพพอร์ท TypeScript เลย ไม่เหมือนกับ &lt;a href="https://dev.to/centrilliontech/deno-v1-0-javascript-runtime-node-js-39jc"&gt;Deno&lt;/a&gt; ที่เพิ่งสร้างขึ้นมาโดยซัพพอร์ท TypeScript เป็นค่า default ตั้งแต่แรก&lt;/p&gt;

&lt;p&gt;เพื่อชีวิตที่ดีกว่า มาเซ็ตโปรเจค Node.js + Express ให้ใช้ TypeScript ได้กันเถอะ!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: ติดตั้ง TypeScript
&lt;/h2&gt;

&lt;p&gt;สำหรับใครที่มี TypeScript อยู่แล้วข้ามสเต็ปนี้ไปได้เลยนะ &lt;/p&gt;

&lt;p&gt;แต่ถ้าใครยังไม่มี ดูวิธีติดตั้งแบบง่ายๆ ได้ที่บทความ &lt;a href="https://www.centrilliontech.co.th/blog/2851/typescript-setup-project/"&gt;สอนวิธีเซ็ตโปรเจค TypeScript / มาใส่ไทป์ให้ JavaScript เพื่อลดความผิดพลาดในการเขียนโค้ดกันดีกว่า&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: เริ่มสร้างโปรเจค
&lt;/h2&gt;

&lt;p&gt;ปกติเราจะเขียนโค้ด Express หน้าตาประมาณนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สมมุติว่าเซฟเป็นไฟล์ชื่อ &lt;code&gt;app.js&lt;/code&gt; ละกัน วิธีที่จะเปลี่ยนมันเป็น TypeScript อย่างแรกเลยคือเปลี่ยนนามสกุลให้กลายเป็น &lt;code&gt;app.ts&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: @types
&lt;/h2&gt;

&lt;p&gt;ปัญหาเมื่อเรานำโค้ด JavaScript ธรรมดามาเปลี่ยนเป็น TypeScript นั่นคือการที่ไทป์หายไป!&lt;/p&gt;

&lt;p&gt;TypeScript Compiler หรือ &lt;code&gt;tsc&lt;/code&gt; ไม่มีทางรู้ได้เลยว่าโค้ดที่เขียนๆ ขึ้นมาใน JavaScript แต่ละตัวมีไทป์เป็นอะไรบ้าง&lt;/p&gt;

&lt;p&gt;ดังนั้นเลยต้องมีการ define ให้ TypeScript รู้จัก ซึ่งการทำแบบนั้นไม่ต้องถึงขั้นเขียนโค้ดใหม่ทั้งหมด แต่แค่เพิ่ม &lt;code&gt;@types&lt;/code&gt; เข้าไปก็พอแล้ว!&lt;/p&gt;

&lt;p&gt;ส่วนการติดตั้งก็ไม่ยาก มี npm ใช้ npm, มี yarn ใช้ yarn&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//npm&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;types&lt;/span&gt;&lt;span class="sr"&gt;/express --save-de&lt;/span&gt;&lt;span class="err"&gt;v
&lt;/span&gt;
&lt;span class="c1"&gt;//yarn&lt;/span&gt;
&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;types&lt;/span&gt;&lt;span class="sr"&gt;/express --de&lt;/span&gt;&lt;span class="err"&gt;v
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;ข้อสังเกตคือ library ยอดนิยมส่วนใหญ่จะมีการทำ types ไว้ให้อยู่แล้ว โดยชื่อของแพกเกจไทป์ส่วนใหญ่จะชื่อเดียวกับชื่อแพกเกจหลัก แต่เติม &lt;code&gt;@types/&lt;/code&gt; ไว้ข้างหน้า&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;จากนั้นเราก็กลับไปแก้โค้ดของเราอีกที&lt;/p&gt;

&lt;p&gt;สำหรับ TypeScript นั้นจะต้องกำหนดไทป์ให้ตัวแปรทุกตัว เช่น &lt;code&gt;Application&lt;/code&gt;, &lt;code&gt;Request&lt;/code&gt;, &lt;code&gt;Response&lt;/code&gt; ซึ่ง import มาจาก &lt;code&gt;express&lt;/code&gt; ได้ตรงๆ เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;เวลาจะใช้งานก็ต้องคอมไพล์ให้ออกมาเป็น &lt;code&gt;.js&lt;/code&gt; ซะก่อนนะ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4: Watch File
&lt;/h2&gt;

&lt;p&gt;จากสเต็ปที่แล้ว จะพบว่าระหว่างการ develop จะมีขั้นตอนเยอะมากในการรัน&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ต้องคอมไพล์ TypeScript ด้วยคำสั่ง &lt;code&gt;tsc&lt;/code&gt; ก่อน&lt;/li&gt;
&lt;li&gt;รัน Node ด้วยคำสั่ง &lt;code&gt;node&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;แล้วถ้ามีการแก้ไข้โค้ดอะไร ก็ต้อง kill process แล้วเริ่มคอมไพล์ตั้งแต่ TypeScript อีกรอบหนึ่งเลย&lt;/li&gt;
&lt;li&gt;ซึ่งเป็นอะไรที่น่ารำคาญและทำให้ Productivity ต่ำมากๆ &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ดังนั้นในสเต็ปสุดท้ายนี้เรามาดูวิธีการเซ็ตคำสั่ง ให้มัน watch file ให้เรากันดีกว่า &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;การ watch file หมายความว่า ให้ node คอยดูถ้าไฟล์ source code ของโปรแกรมมีการเปลี่ยนแปลง (เช่นมีการ save โค้ดตัวใหม่เข้ามา) ให้เริ่มรันโปรแกรมใหม่ด้วยตัวมันเอง เราจะได้ไม่ต้องมาคอยสั่งทุกครั้ง&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ตามปกติถ้าเราเขียน Node.js ธรรมดา เราอาจจะใช้แพ็กเกจ เช่น &lt;code&gt;nodemon&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nodemon app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่ถ้าเราเขียนโค้ดในไฟล์ TypeScript อยู่ เราก็ต้องสั่งให้มัน watch file ด้วยอีกต่อหนึ่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tsc &lt;span class="nt"&gt;--watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;ซึ่งถ้าใช้วิธีนี้จะต้องเปิด Terminal ไว้ 2 อัน อันนึงรัน nodemon อีกอันรัน tsc นะ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;หรือเราอาจจะใช้ &lt;code&gt;ts-node&lt;/code&gt; แทนก็ได้ (อ่านวิธีใช้ &lt;code&gt;ts-node&lt;/code&gt; และวิธีเซ็ต structure ของโปรเจคได้ที่ &lt;a href="https://www.centrilliontech.co.th/blog/2851/typescript-setup-project/"&gt;บทความสอนวิธีเซ็ตโปรเจค TypeScript&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nodemon &lt;span class="nt"&gt;--watch&lt;/span&gt; &lt;span class="s1"&gt;'src/**/*.ts'&lt;/span&gt; &lt;span class="nt"&gt;--ignore&lt;/span&gt; &lt;span class="s1"&gt;'src/**/*.spec.ts'&lt;/span&gt; &lt;span class="nt"&gt;--exec&lt;/span&gt; &lt;span class="s1"&gt;'ts-node'&lt;/span&gt; src/app.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;นั่นคือเราสั่งให้ nodemon คอยดูไฟล์ทั้งหมดในโฟลเดอร์ &lt;code&gt;src&lt;/code&gt; ที่เป็นนามสกุล &lt;code&gt;.ts&lt;/code&gt; ถ้าไฟล์มีการเปลี่ยนแปลง (มีการแก้ไขหรือมีการเซฟใหม่) ให้รันคำสั่ง &lt;code&gt;ts-node&lt;/code&gt; ใหม่ทันที&lt;/p&gt;

&lt;p&gt;หรือถ้าไม่อยากเขียน command ยาวๆ ก็ไปเขียน config ในไฟล์ &lt;code&gt;nodemon.json&lt;/code&gt; แทนก็ได้&lt;/p&gt;

&lt;p&gt;แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"watch"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"ext"&lt;/span&gt;: &lt;span class="s2"&gt;"ts"&lt;/span&gt;,
  &lt;span class="s2"&gt;"ignore"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src/**/*.spec.ts"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"exec"&lt;/span&gt;: &lt;span class="s2"&gt;"ts-node ./src/app.ts"&lt;/span&gt; 
  &lt;span class="c"&gt;#or &lt;/span&gt;
  &lt;span class="s2"&gt;"exec"&lt;/span&gt;: &lt;span class="s2"&gt;"npx ts-node ./src/app.ts"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ใช้ ts-node-dev
&lt;/h3&gt;

&lt;p&gt;หรือใช้อีกวิธีคือลงแพ็กเกจ &lt;code&gt;ts-node-dev&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm&lt;/span&gt;
yarn add ts-node-dev &lt;span class="nt"&gt;--dev&lt;/span&gt;

&lt;span class="c"&gt;# yarn&lt;/span&gt;
npm i ts-node-dev &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แล้วก็รันด้วยคำสั่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ts-node-dev app.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>ทำยังไง? อยากให้ JavaScript เรียกฟังก์ชันในภาษา PHP เขียนโค้ดยังไงนะ</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Sun, 30 Aug 2020 13:12:32 +0000</pubDate>
      <link>https://dev.to/tamemo/javascript-php-25h3</link>
      <guid>https://dev.to/tamemo/javascript-php-25h3</guid>
      <description>&lt;p&gt;หนึ่งในคำถามที่เว็บโปรแกรมเมอร์มือใหม่ถามกันเยอะมากจนน่าจัดเก็บไว้เป็น FAQ เลยก็คือ&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"จะทำยังไงให้เราเรียกใช้ฟังก์ชันภาษา PHP จากสคริป JavaScript ได้"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เช่นแบบนี้...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;?php functionInPhp1(); ?&amp;gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    คลิกฉันสิ!
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หรือแบบนี้...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;functionInJs&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="nx"&gt;php&lt;/span&gt; &lt;span class="nx"&gt;functionInPhp2&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;คำตอบคือ ด้วยการทำงานของเว็บที่ทำงานบนโปรโตคอล http นั้น...มันทำไม่ได้!! (แต่มีวิธีแก้ ถ้าอยากทำจริงๆ อ่านต่อไป!)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;จริงๆ แล้วไม่จำกัดว่าต้องเป็นภาษา PHP เท่านั้นนะ เคสนี้เป็นกับทุกภาษาฝั่งเซิร์ฟเวอร์เลย&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;เพื่อจะตอบว่าทำไมมันทำไม่ได้ เราจะต้องอธิบายการทำงานของ http กันซะก่อน&lt;/p&gt;

&lt;h2&gt;
  
  
  http และ Stateless
&lt;/h2&gt;

&lt;p&gt;http เป็นโปรโตคอลมาตราฐานสำหรับการเขียนเว็บ ซึ่งการทำงานของมันสรุปง่ายๆ ได้ดังนี้&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;โปรโตคอล (Protocol) = กฎที่ตั้งขึ้นมาเพื่อให้คอมพิวเตอร์ในเน็ตเวิร์คสามารถคุยกันด้วยภาษาเดียวกัน ไม่งั้นมันจะคุยกันไม่รู้เรื่อง&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nEB4JhoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-VOh-OfyOCxw/X0uY8UC54II/AAAAAAAASkE/pNpSfpaDfVc-BqekljFVBOjNiHqhlEpZgCNcBGAsYHQ/s1507/js-call-php-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nEB4JhoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-VOh-OfyOCxw/X0uY8UC54II/AAAAAAAASkE/pNpSfpaDfVc-BqekljFVBOjNiHqhlEpZgCNcBGAsYHQ/s1507/js-call-php-1.png" alt="" width="880" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client ส่งคำขอหรือ &lt;code&gt;request&lt;/code&gt; ไปหา Server &lt;/li&gt;
&lt;li&gt;เมื่อ Server ได้รับ &lt;code&gt;request&lt;/code&gt; แล้วก็จะรันสคริปที่เตรียมไว้ เพื่อหาว่าจะตอบอะไรกลับไปให้ Client, ในสเต็ปนี้ อาจจะมีการเชื่อมต่อเพื่อขอข้อมูลจาก database ด้วย&lt;/li&gt;
&lt;li&gt;หลังจาก Server คิดเสร็จ ก็จะส่งคำตอบ (อยู่ในรูปแบบของ String) กลับไปให้ Client &lt;strong&gt;[มาถึงตรงนี้ถือว่า Server ทำงานเสร็จแล้ว!]&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client รับข้อมูลไป (ส่วนใหญ่จะอยู่ในรูปแบบ html) ก็เอาไปแสดงผล แต่ถ้ามีการแนบสคริปมาด้วย ก็จะจัดการรันสคริปตัวนั้นซะในสเต็ปนี้&lt;/li&gt;
&lt;li&gt;จบจ้า!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VFMZY_-A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-FenJv8vff1o/X0uY8GsJ6DI/AAAAAAAASkA/cKpPnBxLX1cKLrQmkMTwLKYAb2vX3dD_wCNcBGAsYHQ/s1599/js-call-php-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VFMZY_-A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-FenJv8vff1o/X0uY8GsJ6DI/AAAAAAAASkA/cKpPnBxLX1cKLrQmkMTwLKYAb2vX3dD_wCNcBGAsYHQ/s1599/js-call-php-2.png" alt="" width="880" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;สำหรับฝั่ง Client นั้นไม่ค่อยมีปัญหาเพราะมีแค่ภาษาเดียวเท่านั้นที่ครอบครองอยู่ นั่นคือ JavaScript แต่ฝั่ง Server นี่มีหลายภาษามากๆ เช่น PHP, Node.js. Go, .NET&lt;/p&gt;

&lt;p&gt;แต่ไม่ว่าฝั่งเซิร์ฟเวอร์จะเขียนด้วยภาษาอะไร หน้าที่ของมันคือส่ง HTML, CSS, JS กลับมาให้ Client เพื่อโปรเซสต่อ&lt;/p&gt;

&lt;p&gt;จะเห็นว่า http เป็นโปรโตคอลง่ายๆ ถามมา-ตอบกลับ แล้วก็จบงาน&lt;/p&gt;

&lt;p&gt;ซึ่งเราเรียกการทำงานแบบนี้ว่า &lt;strong&gt;"Stateless"&lt;/strong&gt; คือทำงานเป็นรอบ พอเรียกใช้งานและทำงานนั้นเสร็จแล้ว ก็จบการทำงาน (เว็บส่วนใหญ่ทำงานแบบนี้)&lt;/p&gt;

&lt;p&gt;ตรงข้ามกับ &lt;strong&gt;"Stateful"&lt;/strong&gt; ที่ตัวโปรแกรมรันค้างอยู่ตลอดเวลา (ให้นึกถึงแอพพลิเคชันมือถือหรือโปรแกรมที่รันใน Desktop)&lt;/p&gt;

&lt;h2&gt;
  
  
  Server ทำงานก่อน Client เสมอ!
&lt;/h2&gt;

&lt;p&gt;เราอธิบายให้ฟังแล้วว่า http นั้นเริ่มทำงานที่ Server รันเพื่อโปรเซสข้อมูลที่จะส่งกลับมาให้ Client ก่อน ... แล้วพอ Client ได้รับข้อมูล (ซึ่งอาจจะมี JavaScript แนบติดมาให้ด้วย) ก็จะเอาสคริปตัวนั้นมารันต่อ&lt;/p&gt;

&lt;p&gt;แสดงว่าในจังหวะที่ Client เริ่มทำงานนั้น ... โค้ดฝั่ง Server ทำงานเสร็จไปแล้ว !&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;นี่เลยเป็นเหตุผลว่าทำไมเราไม่สามารถทำให้ JavaScript เรียกให้ PHP ทำงานได้&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;registerMeeting&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="c1"&gt;//ต้องการบันทึกว่าเข้าร่วมประชุมแล้ว&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getOnlines&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="c1"&gt;//ต้องการดึงรายชื่อคนที่กำลังออนไลน์อยู่ในขณะนี้&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="nf"&gt;registerMeeting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ลงชื่อเข้าประชุม
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getWhoOnlineNow&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;onlines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="nf"&gt;getOnlines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ในโค้ดตัวอย่างนี้เรามีฟังก์ชันในภาษา PHP อยู่ 2 ตัว คือ &lt;code&gt;registerMeeting()&lt;/code&gt; และ &lt;code&gt;getOnlines()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;จากนั้นเราไปเขียนโค้ด JavaScript เพื่อเรียกใช้งานฟังก์ชัน PHP ทั้งสองตัวนี้ต่อ&lt;/p&gt;

&lt;p&gt;แต่ปัญหาก็คือ PHP เป็น Server-Side-Script มันทำงานก่อนเสมอ (ไม่ต้องรอให้ JavaScript เรียกหรอก ฉันทำงานเองตอนนี้เลย!)&lt;/p&gt;

&lt;p&gt;แต่ด้วยโลจิคแล้ว เราต้องการให้ฟังก์ชันพวกนี้ทำงานเมื่อเรามี event เท่านั้น (เชื่อ ปุ่มโดน onclick หรือฟังก์ชัน JavaScript ทำงาน)&lt;/p&gt;

&lt;p&gt;ดังนั้นโค้ดนี้เลยผิด! &lt;/p&gt;

&lt;h2&gt;
  
  
  Asynchronous คือทางแก้
&lt;/h2&gt;

&lt;p&gt;หากต้องการให้ JavaScript เรียกให้ PHP ทำงานได้ มีอยู่วิธีเดียวนั้นคือใช้เทคนิคการเขียนโปรแกรมแบบ Asynchronous &lt;/p&gt;

&lt;p&gt;หรือถ้าจะเรียกด้วยชื่อแบบดังเดิมคือเทคนิคที่เรียกว่า &lt;strong&gt;"Ajax"&lt;/strong&gt; (&lt;strong&gt;A&lt;/strong&gt;synchronous &lt;strong&gt;J&lt;/strong&gt;avaScript &lt;strong&gt;a&lt;/strong&gt;nd &lt;strong&gt;X&lt;/strong&gt;ML) ... แต่ปัจจุบันไม่ค่อยเรียกชื่อนี้กันแล้วนะ และเราก็ไม่ได้ใช้แค่ XML เป็นตัวกลางส่งข้อมูลกันอีกตัวไป มีการใช้ JSON เพิ่มเข้ามาด้วย&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ในบทความนี้จะไม่สอน Ajax แบบละเอียดนะ ถ้าอยากรู้ตามไปอ่านได้ที่ &lt;a href="https://www.tamemo.com/post/37/how-to-ajax-1/"&gt;Ajax คืออะไร แล้วมันใช้ยังไง?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สำหรับ PHP ...&lt;/p&gt;

&lt;p&gt;ให้แยกโค้ดส่วนที่ต้องการให้ JavaScript เรียกใช้งานได้ออกมาอยู่อีกไฟล์หนึ่ง เช่นกรณีนี้ตั้งชื่อไฟล์ว่า &lt;code&gt;async-handler.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;FILE: async-handler.php

&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;registerMeeting&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;//ต้องการบันทึกว่าเข้าร่วมประชุมแล้ว&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getOnlines&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;//ต้องการดึงรายชื่อคนที่กำลังออนไลน์อยู่ในขณะนี้&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'action'&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;'register-meeting'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; 
        &lt;span class="nf"&gt;registerMeeting&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s1"&gt;'get-online-user'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; 
        &lt;span class="nf"&gt;getOnlines&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;และเนื่องจากเรามี action ที่ต้องการให้ทำงานมากกว่า 1 ตัว ก็เลยใช้ query-string ชื่อว่า &lt;code&gt;action&lt;/code&gt; เป็นตัวแยกว่า request ครั้งนี้ต้องการให้ฟังก์ชันไหนทำงาน (ตรงนี้ตั้งชื่อว่าอะไรก็ได้นะ แล้วแต่เลย)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"registerMeeting()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ลงชื่อเข้าประชุม
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;registerMeeting&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/async-handler.php?action=register-meeting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getWhoOnlineNow&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/async-handler.php?action=get-online-user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onlines&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จากนั้น ในฝั่ง JavaScript ก็ใช้การ request กลับไปยังไฟล์ PHP &lt;code&gt;async-handler.php&lt;/code&gt; ที่เตรียมไว้อีกรอบ จะใช้คำสั่ง &lt;code&gt;fetch()&lt;/code&gt; หรือไลบรารี่ Axios หรือถ้าเก่าหน่อยก็ใช้ &lt;code&gt;$.ajax()&lt;/code&gt; ของ jQuery ก็ตามสะดวกเลย&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;การจะให้ JavaScript เรียกคำสั่ง PHP ตรงๆ นั้นทำไม่ได้ เพราะกว่า JavaScript จะเริ่มทำงาน PHP ก็ทำงานจนเสร็จไปก่อนแล้ว&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XyUedulD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-VSzWK6n8NLQ/X0uix11l-0I/AAAAAAAASkU/YS4xQp5zbJIRUW88MNV94_9QBfUSXUlAQCNcBGAsYHQ/s1192/js-call-php-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XyUedulD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-VSzWK6n8NLQ/X0uix11l-0I/AAAAAAAASkU/YS4xQp5zbJIRUW88MNV94_9QBfUSXUlAQCNcBGAsYHQ/s1192/js-call-php-3.png" alt="" width="880" height="685"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;แต่มีวิธีการแก้ทางคือสร้าง request ขึ้นมาอีกครั้งเพื่อเรียกไปหา Server ให้ปลุก PHP ขึ้นมาทำงานอีกรอบหนึ่ง&lt;/p&gt;

&lt;p&gt;คือต้อง request 2 ครั้ง&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ครั้งแรก - ให้ Server ส่ง HTML, CSS, JS มาให้ก่อน&lt;/li&gt;
&lt;li&gt;ครั้งที่สอง - JavaScript สร้าง request อีกครั้ง เรียกไปยังไฟล์ PHP ที่เตรียมเป็น asynchronous handler เอาไว้&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>javascript</category>
      <category>ajax</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>สอนวิธีเซ็ตโปรเจค TypeScript / มาใส่ไทป์ให้ JavaScript เพื่อลดความผิดพลาดในการเขียนโค้ดกันดีกว่า</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Tue, 28 Jul 2020 06:43:35 +0000</pubDate>
      <link>https://dev.to/tamemo/typescript-javascript-5db3</link>
      <guid>https://dev.to/tamemo/typescript-javascript-5db3</guid>
      <description>&lt;p&gt;ภาษา JavaScript นั้นเป็นภาษาที่เริ่มเขียนได้ไม่ยาก ยิ่งถ้าใครเขียนภาษาสาย Structure/OOP เช่น C/C++, C#, Java มาก่อน อาจจะชอบในความเป็น Dynamic Type เราสร้างตัวแปรแล้วเก็บค่าอะไรก็ได้ ทำให้มีความคล่องตัวในการเขียนมากๆ ก่อนที่พอเขียนไปเรื่อยๆ เราจะพบความแปลกของมัน ยิ่งเขียนไปนานๆ เราก็พบว่ามันเป็นภาษาที่ทำให้เกิดบั๊กได้ง่ายมาก และเป็นหนึ่งในภาษาที่น่าปวดหัวที่สุดที่คนโหวตๆ กันเลย ด้วยเหตุผลแรกคือการที่ตัวแปรไม่มี Type นั่นเอง (อีกเหตุผลหนึ่งคือส่วนใหญ่ของคนที่เปลี่ยนมาเขียน JavaScript เคยชินกับภาษาแนว OOP มาก่อน พอมาเขียนภาษาแนว Functional เลยงงหน่อยๆ)&lt;/p&gt;

&lt;h2&gt;
  
  
  หลักการคือคอมไพล์ออกมาเป็น JavaScript
&lt;/h2&gt;

&lt;p&gt;เอาจริงๆ ตัวภาษา TypeScript เอาไปรันอะไรไม่ได้เลย &lt;/p&gt;

&lt;p&gt;แต่เราใช้วิธีการคอมไพล์ไฟล์ &lt;code&gt;.ts&lt;/code&gt; ให้ออกมาเป็นไฟล์ &lt;code&gt;.js&lt;/code&gt; อีกที หน้าที่ของมันมีแค่นั้นเอง&lt;/p&gt;

&lt;p&gt;หรือบางกรณีถ้าเราเขียน React เราอาจจะรู้จักกับ &lt;code&gt;.jsx&lt;/code&gt; สำหรับ TypeScript ก็มีไฟล์นามสกุล &lt;code&gt;.tsx&lt;/code&gt; ให้ใช้เช่นกัน&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation มาติดตั้ง TypeScript กัน
&lt;/h2&gt;

&lt;p&gt;สำหรับ TypeScript Compiler นั้นสามารถติดตั้งได้ทั้งผ่าน &lt;strong&gt;&lt;a href="https://www.npmjs.com/"&gt;npm&lt;/a&gt;&lt;/strong&gt; หรือ &lt;strong&gt;&lt;a href="https://yarnpkg.com"&gt;yarn&lt;/a&gt;&lt;/strong&gt; ด้วยคำสั่งประมาณนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;พอติดตั้งแล้วเราสามารถใช้คำสั่ง &lt;code&gt;tsc&lt;/code&gt; สำหรับคอมไพล์ไฟล์ TypeScript ได้เลย &lt;/p&gt;

&lt;p&gt;วิธีนี้เป็นการติดตั้งแบบ global คือติดตั้งครั้งเดียว ใช้ได้ทุกที่เลย แต่ถ้าอยากติดตั้งแต่ในโปรเจคๆ ไปก็สามารถทำได้ด้วย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install typescript --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หรือจะใช้งานผ่าน npx ก็ได้เช่นกัน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tsc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;flag &lt;code&gt;--save-dev&lt;/code&gt; หรือตัวย่อ &lt;code&gt;-D&lt;/code&gt; ใส้ไว้เพื่อระบุว่าเราใช้แพ็กเกจนี้เฉพาะตอน develop เท่านั้น เมื่อไหร่ที่จะ build โปรเจคเอาไปใช้จริง ไม่ต้องเอาติดไปด้วยนะ เพราะอย่างที่บอกคือ TypeScript นั้นตัวมันไม่ได้เอาไปรัน แต่คอมไพล์เป็น JavaScript เมื่อไหร่ที่เขียนเสร็จแล้ว ก็ไม่ต้องใช้ต่อแล้ว&lt;/p&gt;

&lt;h2&gt;
  
  
  คอมไพล์ไฟล์ TypeScript
&lt;/h2&gt;

&lt;p&gt;เริ่มแรกลองมาสร้างไฟล์ TypeScript กันดีกว่า&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//app.ts&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เขียนโค้ดนี้แล้วเซฟเป็นไฟล์ชื่อ &lt;code&gt;app.ts&lt;/code&gt; ไว้ จะเห็นว่า syntax ทั้งหมดนั้นเหมือนกัน JavaScript ทุกอย่าง ที่เพิ่มเติมมาก็แค่หลังชื่อตัวแปร ตอนที่ประกาศตัวแปรและ parameter เราจะต้องกำหนดชนิดตัวแปรลงไปด้วย โดยใช้ตัว &lt;code&gt;:&lt;/code&gt; ตามแพทเทิร์นนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var-name: type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ไทป์ที่ใช้ได้ก็เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xf00d&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b1010&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;octal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mo"&gt;0o744&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isDone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สำหรับตัวแปรประเภท Array นั้นประกาศได้ 2 แบบคือ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนตัวแปรแบบ Object นั้นจะต้องสร้าง &lt;code&gt;interface&lt;/code&gt; เพื่อกำหนดไทป์ขึ้นมาก่อน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
    &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;myPoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สำหรับ TypeScript นั้น เราไม่สามารถสร้างตัวแปรแบบไม่กำหนดไทป์ได้ แต่ถ้าเราไม่รู้ไทป์จริงๆ เราสามารถประกาศไทป์ &lt;code&gt;any&lt;/code&gt; ได้ (แต่ก็ไม่แนะนำให้ทำนะ)&lt;/p&gt;




&lt;p&gt;จากนั้นเราใช้คำสั่ง &lt;code&gt;tsc&lt;/code&gt; ในการคอมไพล์ไฟล์ TypeScript ของเรา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc app.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;หลังจากคอมไพล์เสร็จแล้ว เราจะได้อีกไฟล์เพิ่มมาในชื่อเดียวกันแต่เป็นนามสกุล &lt;code&gt;.js&lt;/code&gt; แทน&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wDK2YBPF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://3.bp.blogspot.com/-56cikDwtKas/XwM8664jOfI/AAAAAAAASdw/TLsnYlIbd74qoxC4OSAxzrN9sYescrudgCNcBGAsYHQ/s1600/ts-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wDK2YBPF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://3.bp.blogspot.com/-56cikDwtKas/XwM8664jOfI/AAAAAAAASdw/TLsnYlIbd74qoxC4OSAxzrN9sYescrudgCNcBGAsYHQ/s1600/ts-03.png" alt="" width="695" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เมื่อเราเอามาเปิดดูก็จะพบว่ามันมีหน้าตาคล้ายๆ กับโค้ด TypeScript ที่เราเขียนไป แต่ชนิดตัวแปรที่เคยประกาศจะหายไป และอาจจะมีอะไรอีกนิดหน่อยด้วย (เช่นมี &lt;code&gt;;&lt;/code&gt; เพิ่มเข้ามาให้ จากที่เคยใช้ &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; ก็เปลี่ยนเป็น &lt;code&gt;var&lt;/code&gt;) ซึ่งโดยร่วมไม่ได้ทำให้โลจิคเปลี่ยนไปนะ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่งจุดนี้อาจจะทำให้คนที่เพิ่งเริ่มใช้ TypeScript สงสัยว่าถ้ามันแค่ตัด Type ทิ้งไป แล้วทำไมเราไม่เขียน JavaScript ตรงๆ ไปเลยล่ะ?&lt;/p&gt;

&lt;p&gt;เช่นผลคือ TypeScript สามารถช่วยเราในส่วนของการเช็ก Compiler-Time Error ได้&lt;/p&gt;

&lt;p&gt;เช่นโค้ดนี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y4Ip9fTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://2.bp.blogspot.com/-WHzrsW6_x6M/XwXbfapXk2I/AAAAAAAASec/Oa99GBNkQxQco27v0XwZG4rDcWPQH0buwCNcBGAsYHQ/s1600/ts-04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y4Ip9fTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://2.bp.blogspot.com/-WHzrsW6_x6M/XwXbfapXk2I/AAAAAAAASec/Oa99GBNkQxQco27v0XwZG4rDcWPQH0buwCNcBGAsYHQ/s1600/ts-04.png" alt="" width="880" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เราประกาศฟังก์ชันที่ต้องรับ &lt;code&gt;number&lt;/code&gt; แต่เวลาเรียกใช้งาน ดันใส่ &lt;code&gt;string&lt;/code&gt; เข้าไป ถ้าเป็น JavaScript จะสามารถนำไปรันได้ (แต่ผลออกมาจะเกิด Runtime-Error หรือมีโลจิคผิดพลาดตรงไหนจะไม่สามารถรู้ได้เลย)&lt;/p&gt;

&lt;p&gt;แต่สำหรับ TypeScript นั้นจะแจ้งออกมาตั้งแต่ตอนสั่งคอมไพล์เลยว่าเรามีการเขียนผิดพลาดเกิดขึ้นนะ และ Editor ส่วนใหญ่ก็สามารถแสดงผลข้อผิดพลาดพวกนี้แบบ real time ได้อยู่แล้วด้วย ทำให้ไม่ต้องเสียเวลาพิมพ์ไปซะนาน แต่พอเอามารันเพิ่งจะรู้ว่าพิมพ์ผิดไป&lt;/p&gt;

&lt;h2&gt;
  
  
  เริ่มสร้างโปรเจคกันเถอะ
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pf4PmZGg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-JW5T9VTVtrE/XwNGmHBuWUI/AAAAAAAASeE/vlaNoNztwF8-ewXvA_FXiZHqqfg6If5TwCNcBGAsYHQ/s1600/ts-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pf4PmZGg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-JW5T9VTVtrE/XwNGmHBuWUI/AAAAAAAASeE/vlaNoNztwF8-ewXvA_FXiZHqqfg6If5TwCNcBGAsYHQ/s1600/ts-02.png" alt="" width="695" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ในโปรเจคขนาดใหญ่ แน่นอนว่าเราไม่ได้มีแค่ไฟล์ sourcecode แค่ไฟล์สองไฟล์ แต่อาจจะมีเป็นร้อยๆ ไฟล์ การจะมานั่งคอมไพล์ TypeScript ทีละไฟล์นั้นทำไม่ได้แน่นอน (จริงๆ ก็ทำได้ แต่ใครจะทำนะ !)&lt;/p&gt;

&lt;p&gt;การสร้างโปรเจคเลยเป็นทางเลือกที่ดีกว่า เช่นเราอาจจะสร้างโฟลเดอร์ &lt;code&gt;/src&lt;/code&gt; สำหรับเอาไว้เก็บไฟล์ &lt;code&gt;.ts&lt;/code&gt; ทั้งหมด และสร้างโฟลเดอร์ &lt;code&gt;/dist&lt;/code&gt; หรือ distribute เอาไว้เก็บไฟล์ JavaScript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── src
│   ├── app1.ts
│   ├── app2.ts
│   ├── app3.ts
│   └── ...
└── dist
    ├── app1.js
    ├── app2.js
    ├── app3.js
    └── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่งสำหรับ TypeScript เราสามารถใช้คำสั่งนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เพื่อกำหนดว่าโฟลเดอร์นั้นจะเป็นโปรเจค TypeScript ได้ หลังจากสั่งคำสั่งนั้นแล้ว เราจะได้ไฟล์ &lt;code&gt;tsconfig.json&lt;/code&gt; มา ภายในไฟล์จะมี config สำหรับโปรเจคอยู่ หน้าตาประมาณนี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MwdX4dpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-nS5sIv3w8nE/XwM861Tx40I/AAAAAAAASds/kuO7AwC5oycilnAC8cqnddf22luEmnqxACNcBGAsYHQ/s1600/ts-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MwdX4dpo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-nS5sIv3w8nE/XwM861Tx40I/AAAAAAAASds/kuO7AwC5oycilnAC8cqnddf22luEmnqxACNcBGAsYHQ/s1600/ts-01.png" alt="" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;รายละเอียดการเซ็ตค่า tsconfig สามารถดูได้ที่เว็บไซต์ของ &lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html"&gt;TypeScript&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ปกติการตั้งค่าหลักๆ ก็จะใช้ของที่ TypeScript สร้างมาให้ ยกเว้นบางตัวที่เราต้องเซ็ตเอง เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;สั่งให้คอมไพล์ออกมาเป็น&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JavaScript&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ES&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ชื่อโหลเดอร์ที่&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ไฟล์&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JavaScript&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ที่คอมไพล์แล้ว&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ชื่อโฟลเดอร์&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sourcecode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ไฟล์&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;TypeScript&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;หากใช้งานกับ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;React&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;คือมีไฟล์&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.tsx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ให้คอมไพล์เป็น&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.jsx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ด้วย&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;หากใช้กับ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;node&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;กำหนดขอบเขตของไฟล์ที่จะให้คอมไพล์&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;เช่น&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ทุกไฟล์ที่นามสกุล&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.ts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ในโฟลเดอร์ไหนก็ได้ใต้&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/src&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"src/**/*.ts"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;กำหนดไฟล์และโฟลเดอร์ที่ไม่ต้องคอมไพล์&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;เช่นโฟลเดอร์&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;node_modules&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;หรือไฟล์&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;spec&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"**/*.spec.ts"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จากนั้นเวลาเราจะคอมไพล์ ก็สั่งแค่&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;มันก็จะเป็นการคอมไพล์ทุกไฟล์ในทั้งโฟลเดอร์ &lt;code&gt;/src/&lt;/code&gt; ที่เรากำหนดไว้&lt;/p&gt;

&lt;p&gt;แต่นี่ก็เป็นการคอมไพล์แค่ครั้งเดียว ถ้าเรามีการแก้ไขไฟล์ TypeScript เพิ่ม เราก็ต้องสั่งคอมไพล์อีกรอบ ถ้าไม่อยากจะมาสั่งคอมไพล์ทุกรอบที่แก้ไขโค้ด เราสามารถสั่งคอมไพล์แบบ watch ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc --watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;คำสั่งนี้จะเป็นการสั่งให้คอมไพล์พร้อมกับ watch หรือคอยดูไฟล์ทุกไฟล์เอาไว้ด้วย ถ้ามีการเปลี่ยนแปลงให้คอมไพล์ใหม่ทันทีโดยเราไม่ต้องสั่งอีกรอบ&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>[How To] การติดตั้ง Google Maps for Flutter เบื้องต้น</title>
      <dc:creator>natcha.s_</dc:creator>
      <pubDate>Thu, 23 Jul 2020 09:10:54 +0000</pubDate>
      <link>https://dev.to/tamemo/how-to-google-maps-for-flutter-14jc</link>
      <guid>https://dev.to/tamemo/how-to-google-maps-for-flutter-14jc</guid>
      <description>&lt;p&gt;วันนี้ผมจะมาแนะนำและวิธีการใช้งานเบื้องต้นของ plugin ที่น่าสนใจตัวหนึ่งที่มีชื่อว่า &lt;br&gt;
"Google Maps for Flutter" &lt;br&gt;&lt;br&gt;
โดย plugin ตัวนี้จะให้ Google Maps ที่เป็น Widget มาให้เราได้เปิดใช้งานแผนที่ของกูเกิ้ล&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eGwgBKBe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-siXqlvlL0e0/Xwbpw5apCWI/AAAAAAAAAC0/uHJAPJtGIREEKvxT9FlnPq1GaZPoJoZrACLcBGAsYHQ/s650/Screen%252BShot%252B2563-07-09%252Bat%252B16.54.28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eGwgBKBe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-siXqlvlL0e0/Xwbpw5apCWI/AAAAAAAAAC0/uHJAPJtGIREEKvxT9FlnPq1GaZPoJoZrACLcBGAsYHQ/s650/Screen%252BShot%252B2563-07-09%252Bat%252B16.54.28.png" alt="" width="650" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  ขั้นตอนการติดตั้ง
&lt;/h3&gt;

&lt;p&gt;อันดับแรก เราต้องทำการขอ API Key ที่ลิ้งค์ &lt;a href="https://cloud.google.com/maps-platform/"&gt;https://cloud.google.com/maps-platform/&lt;/a&gt; &lt;br&gt;&lt;br&gt;
 เมื่อเข้ามาหน้าเว็บไซต์แล้วให้เข้าไปที่ Console (ตรงขวามุมบนของหน้าจอ)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1fBgBelQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-8aU2-uliQeI/Xwbr46p60uI/AAAAAAAAADE/fSFVTh5p-34IGiPEKBfyvY_LDZR1oP5YACLcBGAsYHQ/s2372/1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1fBgBelQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-8aU2-uliQeI/Xwbr46p60uI/AAAAAAAAADE/fSFVTh5p-34IGiPEKBfyvY_LDZR1oP5YACLcBGAsYHQ/s2372/1.png" alt="" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;สร้าง Project ของเราขึ้นมาก่อน&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8VvX6y4x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-0FSM5Aw3ze0/XwbtIaCUiEI/AAAAAAAAADQ/6iEKW3lrgEMgX1CZPv8YmCFXm-5WuEMxQCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.09.41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8VvX6y4x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-0FSM5Aw3ze0/XwbtIaCUiEI/AAAAAAAAADQ/6iEKW3lrgEMgX1CZPv8YmCFXm-5WuEMxQCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.09.41.png" alt="" width="880" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เมื่อทำการสร้างเสร็จแล้วให้เปิดแท็บด้านขวามือ แล้วเลือกเมนูที่ชื่อว่า Google Maps&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DNaC6E-N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-PiZD8uSAl1I/Xwbt0bC6dGI/AAAAAAAAADY/1Ijcrk2BMzQMcqpZMjI47C3xm6kbE9fAwCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.13.17.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DNaC6E-N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-PiZD8uSAl1I/Xwbt0bC6dGI/AAAAAAAAADY/1Ijcrk2BMzQMcqpZMjI47C3xm6kbE9fAwCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.13.17.png" alt="" width="880" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Maps จะมี​ API ให้ใช้หลายตัว เราสามารถเข้าไป Enable เพื่อที่จะเรียกใช้ API เหล่านั้นได้ &lt;br&gt;&lt;br&gt;
แต่ตอนนี้เราจะเลือก Enable Maps SDK for Android / IOS เพื่อที่จะเอา API Key ไปเรียกใช้งาน API เหล่านี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VuNH7MWp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-6-m497ds9_0/XwbuYDcCN7I/AAAAAAAAADg/b-LEZEbVOOoMgyZeANK5_hsUN-etR3WogCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.15.41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VuNH7MWp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-6-m497ds9_0/XwbuYDcCN7I/AAAAAAAAADg/b-LEZEbVOOoMgyZeANK5_hsUN-etR3WogCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.15.41.png" alt="" width="880" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ต่อมาให้เข้าไปที่เมนู Credentials เพื่อที่จะสร้าง API Key เอาไปแปะในโค้ดให้เชื่อมต่อกับ Google Cloud Platform &lt;br&gt;&lt;br&gt;
กดเลือก Create Credentials -&amp;gt; API Key&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mctmYZ1Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-eGjjbtDPREA/XwbwnqBSppI/AAAAAAAAADs/VDgtQzy3W-sAIddxl6pK7AQqmmCniX-ygCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.24.49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mctmYZ1Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-eGjjbtDPREA/XwbwnqBSppI/AAAAAAAAADs/VDgtQzy3W-sAIddxl6pK7AQqmmCniX-ygCLcBGAsYHQ/s2372/Screen%252BShot%252B2563-07-09%252Bat%252B17.24.49.png" alt="" width="880" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เราก็จะได้ API Key มาเท่านี้ก็จะสามารถเชื่อมต่อกับ Google Map Api ได้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--baVYaXMC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-BJedIQDH4QA/XwbxXVuwoMI/AAAAAAAAAD4/eEW6JBcVWlIpkXiNj_C_hPkLxpzLosFGACLcBGAsYHQ/s2368/Screen%252BShot%252B2563-07-09%252Bat%252B17.27.16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--baVYaXMC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-BJedIQDH4QA/XwbxXVuwoMI/AAAAAAAAAD4/eEW6JBcVWlIpkXiNj_C_hPkLxpzLosFGACLcBGAsYHQ/s2368/Screen%252BShot%252B2563-07-09%252Bat%252B17.27.16.png" alt="" width="880" height="358"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  มาในส่วนของการเขียนโค้ดกันบ้าง
&lt;/h3&gt;

&lt;p&gt;สำหรับ Android ให้เข้าไปเพิ่ม API Key ที่ไฟล์ AndroidManifest.xml ในโฟลเดอร์ &lt;br&gt;
Android (android/app/src/main/AndroidManifest.xml)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
└── android
    └── app
        └── src
            └── main
                └── AndroidManifest.xml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ให้เพิ่ม &lt;code&gt;&amp;lt;uses-permission/&amp;gt;&lt;/code&gt; เพื่อขอ permission &lt;br&gt;
กับ &lt;code&gt;&amp;lt;meta-data/&amp;gt;&lt;/code&gt; เพื่อเพิ่ม API KEY เข้าไป&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt; &lt;span class="nl"&gt;xmlns:&lt;/span&gt;&lt;span class="n"&gt;android&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt;
    &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"com.example.fluttergooglemap"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.ACCESS_FINE_LOCATION"&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;uses&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"android.permission.ACCESS_COARSE_LOCATION"&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;
        &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"io.flutter.app.FlutterApplication"&lt;/span&gt;
        &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fluttergooglemap"&lt;/span&gt;
        &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"@mipmap/ic_launcher"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"com.google.android.geo.API_KEY"&lt;/span&gt;
            &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"YOUR API KEY"&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;activity&lt;/span&gt;
            &lt;span class="nl"&gt;android:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;".MainActivity"&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สำหรับ IOS เข้าไปที่ไฟล์ AppDelegate.swift (ios/Runner/AppDelegate.swift)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
└── ios
    └── Runner
        ├── AppDelegate.swift
        └── Info.plist

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เพิ่ม API KEY เข้าไป &lt;code&gt;GMSServices.provideAPIKey("YOUR KEY HERE")&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@UIApplicationMain&lt;/span&gt;
&lt;span class="nd"&gt;@objc&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppDelegate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FlutterAppDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nl"&gt;application:&lt;/span&gt; &lt;span class="n"&gt;UIApplication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;didFinishLaunchingWithOptions&lt;/span&gt; &lt;span class="nl"&gt;launchOptions:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UIApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LaunchOptionsKey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;GMSServices&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;provideAPIKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"YOUR API KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;GeneratedPluginRegistrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;didFinishLaunchingWithOptions:&lt;/span&gt; &lt;span class="n"&gt;launchOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;และเข้าไปที่ไฟล์ info.plist เพิ่มคำส่ัง เพื่อขอ permission&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NSLocationWhenInUseUsageDescription&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Google&lt;/span&gt; &lt;span class="n"&gt;Maps&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;embedded_views_preview&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เข้าไปที่ไฟล์ pubspec.yaml &lt;br&gt;
ติดตั้ง &lt;code&gt;google_maps_flutter: ^0.5.28+1&lt;/code&gt; (เวอร์ช้่นล่าสุดเมื่อ May 21, 2020) &lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;flutter:&lt;/span&gt;
    &lt;span class="nl"&gt;sdk:&lt;/span&gt; &lt;span class="n"&gt;flutter&lt;/span&gt;

  &lt;span class="nl"&gt;google_maps_flutter:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;import Libray&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:google_maps_flutter/google_maps_flutter.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;สร้างตัวแปรประเภท &lt;code&gt;GoogleMapController&lt;/code&gt; คือ class ที่เอาไว้สร้าง Future อีกที เอาไว้ควบคุมการทำงาน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyHomePageState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyHomePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GoogleMapController&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Library จะมี Widget มาให้ชื่อว่า &lt;code&gt;GoogleMap()&lt;/code&gt; &lt;br&gt;
ทดลองพิมพ์ตามโค้ดด้านล่างนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt; &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;GoogleMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;initialCameraPosition:&lt;/span&gt; &lt;span class="n"&gt;CameraPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;target:&lt;/span&gt; &lt;span class="n"&gt;LatLng&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;13.757429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;100.502465&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;//กำหนดพิกัดเริ่มต้นบนแผนที่&lt;/span&gt;
          &lt;span class="nl"&gt;zoom:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//กำหนดระยะการซูม สามารถกำหนดค่าได้ 0-20&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;onMapCreated:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GoogleMapController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เริ่มต้น GoogleMap จะต้อง &lt;code&gt;initialCameraPosition&lt;/code&gt; เสมอ โดยกำหนดพิกัดจุดเริ่มต้นสถานที่จะให้ GoogleMap แสดงขึ้นมา แล้วลอง Run&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uxphZ7jr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-q9eF89m8xFg/XxlSMH_TCYI/AAAAAAAAAE8/hLndX_a9brIxyz7o1-18rHLjjUiCyyNkwCLcBGAsYHQ/s450/Screen%252BShot%252B2563-07-23%252Bat%252B15.54.33.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uxphZ7jr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://1.bp.blogspot.com/-q9eF89m8xFg/XxlSMH_TCYI/AAAAAAAAAE8/hLndX_a9brIxyz7o1-18rHLjjUiCyyNkwCLcBGAsYHQ/s450/Screen%252BShot%252B2563-07-23%252Bat%252B15.54.33.png" alt="" width="278" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เพียงเท่านี้ก็จะสามารถเปิดกูเกิ้ลแมพได้ บทความนี้จะเป็นการติดตั้งเบื้องต้น และบทความต่อไปจะเป็นการใช้งานเบื้องต้นเกี่ยวกับ GoogleMap, Polyline, Marker &lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>รู้จักกับ TypeScript - ประวัติของภาษาที่เติมไทป์ให้กับ JavaScript</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Thu, 23 Jul 2020 04:17:47 +0000</pubDate>
      <link>https://dev.to/tamemo/typescript-javascript-4n2</link>
      <guid>https://dev.to/tamemo/typescript-javascript-4n2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;ในบทความนี้จะเล่าถึงที่มาที่ไปของ TypeScript อย่างเดียวนะ ส่วนเรื่องสอนว่าใช้งานยังไงได้บ้าง จะเขียนอีกทีในบล็อกต่อๆ ไป&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สำหรับภาษาโปรแกรมทุกวันนี้ ถ้าแบ่งคร่าวๆ ด้วยชนิดของตัวแปร เราจะแบ่งได้ 2 อย่าง คือ &lt;strong&gt;Static Type&lt;/strong&gt;: ต้องกำหนดชนิดตัวแปร เช่น &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt; ตั้งแต่สร้างตัวแปร และ &lt;strong&gt;Dynamic Type&lt;/strong&gt; ตัวแปรประเภทนี้ไม่ต้องบอกว่าเก็บค่าชนิดไหน เปลี่ยนไปได้เรื่อยๆ&lt;/p&gt;

&lt;p&gt;สำหรับภาษาแบบ Dynamic Type ที่ไม่ต้องกำหนดชนิดตัวแปรให้แน่นอน จะเซ็ตค่าเป็นอะไรก็ได้นั้นอาจจะทำให้เขียนง่าย แถมบางภาษาเช่น Python ไม่ต้องประกาศตัวแปรก่อนใช้ด้วยซ้ำ อยากใช้ก็ใช้เลย&lt;/p&gt;

&lt;h3&gt;
  
  
  Static Type
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"str"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Type Error!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dynamic Type
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;str&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;#Ok!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับระยะยาวและโปรเจคขนาดใหญ่ที่มีความซับซ้อนสูงมากๆ การที่ไม่ต้องประกาศ/กำหนดชนิดตัวแปรทำให้เกิดปัญหาตามมามากมาย ยิ่งถ้าต้องทำงานเป็นทีมร่วมกันแล้ว ถ้าเราไม่รู้ว่าตัวแปรตัวนี้เป็นชนิดอะไร จะทำให้เสียเวลาไล่โค้ดนานมาก&lt;/p&gt;

&lt;p&gt;ลองดูตัวอย่างต่อไปนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum_product_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;products&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จะเห็นว่าการที่ตัวแปรสร้างเป็นไทป์อะไรก็ได้ทำให้เวลาอ่าน/แก้ไขโค้ดทำได้ยากมาก เพราะไม่รู้ structure ของตัวแปร เช่น &lt;code&gt;data&lt;/code&gt; ที่เราต้องมาจำเองว่ามันมีฟิลด์ชื่อ &lt;code&gt;products&lt;/code&gt; และเป็นอ็อบเจคที่มี &lt;code&gt;.price&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;โค้ดที่เขียนเองอาจจะไม่เท่าไหร่ แต่ถ้าเป็นโค้ดที่เขียนต่อจากคนอื่น อันนี้มีงงแน่นอน&lt;/p&gt;

&lt;p&gt;ช่วงหลังๆ มีหลายภาษาที่เริ่มต้นจากการเป็นภาษา Dynamic Type แต่ก็ต้องเพิ่มฟีเจอร์ให้กำหนดตัวแปรได้มาภายหลัง เช่น PHP (กำหนดไทป์ได้ตั้งแต่เวอร์ชัน 7) และ Python (กำหนดไทป์ได้ตั้งแต่เวอร์ชัน 3.6)&lt;/p&gt;

&lt;p&gt;JavaScript ก็เป็นหนึ่งในนั้น แต่สำหรับ JavaScript นั้นมีความแปลกกว่าภาษาอื่นนิดหน่อย เพราะถ้าเราต้องการใช้ไทป์ในภาษานี้ เราจะต้องเขียนมันด้วย TypeScript ซึ่งเป็นภาษาอีกตัวหนึ่งจากทาง Microsoft ที่พอเขียนเสร็จแล้วมันจะคอมไพล์กลับมาเป็น JavaScript อีกทีหนึ่ง&lt;/p&gt;

&lt;p&gt;ดังนั้นคำแนะนำในการเขียน JavaScript ข้อแรกคือ .. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;อย่าเขียน JavaScript แต่ให้เขียน TypeScript แทน !!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  กำเนิด TypeScript
&lt;/h2&gt;

&lt;p&gt;TypeScript นั้นถูกสร้างโดย Microsoft  หลังจากที่ &lt;strong&gt;VBScript&lt;/strong&gt; ของตัวเองแพ้ให้กับ JavaScript&lt;/p&gt;

&lt;p&gt;Microsoft ใช้หลักการว่า "ถ้าต้านไม่อยู่ ก็เข้าร่วมซะ" โดยมอบหมายงานนี้ให้กับ นักออกแบบภาษาโปรแกรมที่เคยออกแบบ C# และ .NET Framework มาแล้วอย่าง &lt;a href="https://en.wikipedia.org/wiki/Anders_Hejlsberg" rel="noopener noreferrer"&gt;Anders Hejlsberg&lt;/a&gt; ซึ่งคอนเซ็ปที่เขาใช้ก็คือเพิ่ม Type ให้กับ JS ซะ&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TypeScript = JavaScript + Type&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;แนวคิดนี้เหมือนกับตอนที่ &lt;strong&gt;C++&lt;/strong&gt; ถูกสร้างขึ้นมาคือเป็นการเพิ่มความสามารถให้ภาษา &lt;strong&gt;C&lt;/strong&gt; อีกที (ในเวอร์ชันแรก C++ นั้นคอมไพล์ออกมาเป็นโค้ดภาษา C)&lt;/p&gt;

&lt;p&gt;ครั้งนี้ก็เช่นกัน ภาษาใหม่ที่ออกแบบจะไม่ฉีกแนวไปจาก JavaScript เลย แต่เพิ่ม syntax ที่บวกความสามารถเรื่อง Type และอื่นๆ เข้าไปแทน โดยตัว TypeScript นี้ไม่ใช่ภาษาที่เอาไปรันได้ แต่ตัวมันคอมไพล์แล้ว output ออกมาเป็น JavaScript นั้นเอง&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-56cikDwtKas%2FXwM8664jOfI%2FAAAAAAAASdw%2FTLsnYlIbd74qoxC4OSAxzrN9sYescrudgCNcBGAsYHQ%2Fs1600%2Fts-03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-56cikDwtKas%2FXwM8664jOfI%2FAAAAAAAASdw%2FTLsnYlIbd74qoxC4OSAxzrN9sYescrudgCNcBGAsYHQ%2Fs1600%2Fts-03.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จริงๆ ต้องบอกว่า Alternative Language หรือภาษาที่เอามาเขียนแทน JavaScript ได้นั้นมีเยอะมาก เช่น CoffeeScript หรือภาษา Functional อย่าง Clojure&lt;/p&gt;

&lt;p&gt;แต่ทำไมอยู่ๆ TypeScript ถึงดังขึ้นมาล่ะ? ทั้งที่ตอนนั้นกระแสโปรแกรมเมอร์ไม่ชอบ Microsoft เยอะมาก (ย้อนกลับไปช่วงต้นปี 2010 นะ) อะไรที่ Microsoft ทำในช่วงนั้น คนจะหนีกันหมด&lt;/p&gt;

&lt;p&gt;จริงๆ แล้วตอนแรก TypeScript ก็ไม่ได้รับความนิยมอะไรมากหรอก &lt;/p&gt;

&lt;p&gt;จน Google มีโปรเจคสร้างเฟรมเวิร์คสำหรับเขียน Frontend ตัวใหม่ที่ชื่อว่า AngularJS ออกมานั่นแหละ &lt;/p&gt;

&lt;p&gt;ตอนนั้น AngularJS กำลังอยู่ในเวอร์ชัน 1 (เขียนด้วย JavaScript เพียวๆ เลย) และทาง Google ก็พบปัญหามากมาย จนอยากจะรื้อเขียนใหม่ให้เป็นเวอร์ชัน 2 ซะ แล้วไหนๆ ก็จะเขียนใหม่แล้ว เขียนมันด้วย ES6 เลยดีกว่า! (ในปีนั้นมาตราฐาน ES6 ยังไม่ออก) จะรอให้มาตราฐานออก ก็ไม่รู้ว่าจะมาเมื่อไหร่ งั้นก็ลองไปค้นๆ ในตลอดดูซิว่าตอนนี้มีภาษาอะไรเอามาใช้แทนก่อนได้มั้ย?&lt;/p&gt;

&lt;p&gt;และหวยก็ไปออกที่ TypeScript นั่นเอง !!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.blognone.com%2Fsites%2Fdefault%2Ffiles%2Fexternals%2F5fee8421cab6a64a1999b937efa4ab9f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.blognone.com%2Fsites%2Fdefault%2Ffiles%2Fexternals%2F5fee8421cab6a64a1999b937efa4ab9f.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;คือตอนนั้นทีม Angular สร้างภาษาของตัวเองชื่อ &lt;strong&gt;ATScript&lt;/strong&gt; ขึ้นมาเพื่อครอบ TypeScript อีกที แต่ก็เปลี่ยนใจยกเลิกไป แล้วหันมาใช้ TypeScript เพียวๆ แทน&lt;/p&gt;

&lt;p&gt;และเมื่อ Angular ดังขึ้น --&amp;gt; TypeScript ก็เลยดังขึ้นมาพร้อมๆ กัน&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2F6Q53fdo58CyIGr3L7SpxE6ymyst9T27Z7z3bAODmzL__LSRVwJBodwWRpBNIumDb-9iYoOebFk01ksw5iuy1Hr0egejLjGm0rleKI5uoQ2U9axFv7sPgtucLSErizwhKNZ7sWOgd" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2F6Q53fdo58CyIGr3L7SpxE6ymyst9T27Z7z3bAODmzL__LSRVwJBodwWRpBNIumDb-9iYoOebFk01ksw5iuy1Hr0egejLjGm0rleKI5uoQ2U9axFv7sPgtucLSErizwhKNZ7sWOgd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุป
&lt;/h2&gt;

&lt;p&gt;TypeScript เป็นแค่ภาษาที่เพิ่ม Type เข้ามาให้ภาษา JavaScript ซึ่งก็อาจจะถือว่าเป็นภาษาดวงดี ออกมาถูกจังหวะ จนทุกวันนี้ได้รับความนิยมสูงมาก โปรเจคใหญ่ๆ ไม่ว่าจะเป็น Node.js, React, Vue.js ล้วนแต่เอา TypeScript ไปผสมได้ทั้งนั้น (ถ้าเป็น Deno, Angular นั้นซัพพอร์ท TypeScript ตั้งแต่แรกอยู่แล้ว)&lt;/p&gt;

&lt;p&gt;บล็อกต่อไปเราจะสอนวิธีการเซ็ตโปรเจค TypeScript ในโปรเจค Node.js กัน&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Async in Dart (5) รู้จักกับ FutureBuilder/StreamBuilder, ตัวช่วยสร้าง Async-Widget ใน Futter</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Tue, 09 Jun 2020 17:17:03 +0000</pubDate>
      <link>https://dev.to/tamemo/async-in-dart-5-futurebuilder-streambuilder-async-widget-futter-21f6</link>
      <guid>https://dev.to/tamemo/async-in-dart-5-futurebuilder-streambuilder-async-widget-futter-21f6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;เนื้อหาในบทนี้ เป็นคลาสเฉพาะที่มากับ Flutter Framework เท่านั้น .. ถ้าเขียน Dart ธรรมดาจะไม่มีให้ใช้นะ!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;เอาจริงๆ 99% ของคนที่ศึกษาภาษา Dart ก็เพื่อเอาไปเขียนแอพ (หรือเว็บ/เด็กส์ท็อป) แบบ cross-platform ด้วยเฟรมเวิร์ก &lt;strong&gt;Flutter&lt;/strong&gt; นั่นแหละ&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ตามความคิดของเรา จริงๆ Flutter น่าจะเลือกภาษา Kotlin มาใช้แทนมากกว่า แต่ก็มีเหตุผลหลายๆ อย่างนั่นแหละที่ทำให้ทำไม่ได้&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;สำหรับการเขียน Flutter นั้น ส่วนประกอบในแต่ละส่วนของแอพนั้นจะพูดออกแบบมาเป็น Component เอามาประกอบเข้าด้วยกันเป็นชั้นๆ เรียกว่า &lt;strong&gt;"Widget"&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;มี Widget อยู่ 2 ประเภทหลักๆ คือ &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;StatelessWidget&lt;/code&gt;: เป็น Widget ที่ไม่สามารถเปลี่ยนแปลงได้หลังจาก render ไปแล้ว &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;StatefulWidget&lt;/code&gt;: เป็น Widget ที่สามารถ render หน้าตา UI ของแอพใหม่ได้ถ้ามีการเปลี่ยนแปลงข้อมูล&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ในบทความนี้เราจะโฟกัสกันที่ &lt;code&gt;StatefulWidget&lt;/code&gt; เป็นหลักนะ หน้าตาของ StatefulWidget ก็จะเป็นประมาณนี้ (StatefulWidget จะมาพร้อมกับคลาส State ของมันเสมอ)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyHomePage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;MyHomePage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;MyHomePageState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MyHomePageState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyHomePageState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyHomePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'This is my App.'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เมธอดหลักที่ทำหน้าที่ในการกำหนดส่วนแสดงผลหรือ UI คือเมธอด &lt;code&gt;build()&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;แน่นอน เวลาเราเขียนแอพจริงๆ โครงสร้างมันจะเป็นการเอา Widget มาซ้อนกันหลายๆๆๆ ชั้นมากๆ เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'This is my App.'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;          
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ทีนี้ ปัญหามันก็อยู่ตรงนี้แหละ เพรายิ่งโครงสร้างซ้อนกันหลายชั้นมากๆ ถ้ามีการเปลี่ยนแปลงข้อมูล ก็ต้อง render หน้านี้ใหม่ (เรียกคำสั่ง &lt;code&gt;build()&lt;/code&gt; ใหม่) แม้ว่าเราจะเปลี่ยนแปลงข้อมูลแค่ไม่กี่จุดเล็กๆ ก็ตาม&lt;/p&gt;

&lt;p&gt;ลองมาดูตัวอย่างแอพมาตราฐานคือ Counter กัน (แอพตัวอย่างนี้เป็นแอพที่เวลาเราสั่ง new Flutter project มันจะสร้างให้เป็น default เลย)&lt;/p&gt;

&lt;p&gt;แต่เราจะขอตัดมาแค่ส่วนที่จะใช้อธิบายนะ และขอแยก Widget ออกเป็นชิ้นๆ ด้วย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyHomePageState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyHomePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;_incrementCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;_counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Scaffold'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;columnWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;columnWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Column Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;incrementButtonWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;counterWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;incrementButtonWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Increment Button Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RaisedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;incrementButtonTextWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;_incrementCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;incrementButtonTextWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Increment Button Text Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Increment'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;counterWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Counter Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'count is &lt;/span&gt;&lt;span class="si"&gt;$_counter&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เมื่อเราเปิดหน้าแอพขึ้นมาครั้งแรก เราจะพบว่า &lt;code&gt;build()&lt;/code&gt; เริ่มทำงาน โดยมันจะเรนเดอร์ Widget ทุกชิ้นขึ้นมาก่อน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render - Scaffold
render - Column Widget
render - Increment Button Widget
render - Increment Button Text Widget
render - Counter Widget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จากนั้น เมื่อเรากด increment จะทำให้เมธอด &lt;code&gt;_incrementCounter()&lt;/code&gt; ทำงาน ไปทำการ &lt;code&gt;setState()&lt;/code&gt; เพื่อเปลี่ยนค่า &lt;code&gt;_counter&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;ผลที่ได้คือเมื่อ state เปลี่ยนไป ทั้งหน้าจะต้องทำการเรนเดอร์ใหม่อีกครั้ง เมธอด build() ก็ต้องเริ่มทำงานใหม่ตั้งแต่ต้นอีกครั้ง ทำให้เราได้ผลแบบนี้ออกมาอีกที&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render - Scaffold
render - Column Widget
render - Increment Button Widget
render - Increment Button Text Widget
render - Counter Widget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่จริงๆ แล้วส่วนที่มีการเปลี่ยนแปลงจริงๆ มีแค่วิดเจ็ต &lt;code&gt;Text('count is $_counter')&lt;/code&gt; เท่านั้น&lt;/p&gt;

&lt;p&gt;ทางทีม Flutter ของ Google เลยแนะนำมาว่าการเขียนแอพแบบนี้จะทำให้ประสิทธิภาพไม่ดี ถ้ามีข้อมูลแปลี่ยนเป็นบางตัว เราควรจะเรนเดอร์ใหม่เฉพาะวิดเจ็ตที่จำเป็นน่าจะดีกว่า&lt;/p&gt;

&lt;p&gt;นั่นเลยเป็นที่มาของวิดเจ็ตพิเศษที่ชื่อว่า &lt;code&gt;FutureBuilder&lt;/code&gt; และ &lt;code&gt;StreamBuilder&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  FutureBuilder / StreamBuilder
&lt;/h2&gt;

&lt;p&gt;มีวิธีการสร้างแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;FutureBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;future:&lt;/span&gt; &lt;span class="n"&gt;_future&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AsyncSnapshot&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;StreamBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;stream:&lt;/span&gt; &lt;span class="n"&gt;_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AsyncSnapshot&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนวิธีการใช้งานนั้นง่ายมาก คือวิดเจ็ตตัวไหนที่สามารถเรนเดอร์ใหม่ได้เฉพาะส่วน ให้เอา FutureBuilder ไม่ก็ StreamBuilder ครบมันลงไป แบบนี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_IWFHtJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://4.bp.blogspot.com/-nbD1G_yRK1o/XuCe0B-LaoI/AAAAAAAASb0/UQi4D43_xp8sRg5Axq5TPxoLb2TpfRTPwCNcBGAsYHQ/s1600/Screen%252BShot%252B2020-06-10%252Bat%252B15.50.05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_IWFHtJV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://4.bp.blogspot.com/-nbD1G_yRK1o/XuCe0B-LaoI/AAAAAAAASb0/UQi4D43_xp8sRg5Axq5TPxoLb2TpfRTPwCNcBGAsYHQ/s1600/Screen%252BShot%252B2020-06-10%252Bat%252B15.50.05.png" alt="" width="880" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  แล้วเมื่อไหร่จะใช้ Future / Stream
&lt;/h3&gt;

&lt;p&gt;ถ้าข้อมูลของเราเปลี่ยนแปลงได้แค่ครั้งเดียว เราจะใช้ FutureBuilder เช่นต้องการโหลดข้อมูลจาก API แค่ครั้งเดียว&lt;/p&gt;

&lt;p&gt;แต่ถ้าข้อมูลของเราเปลี่ยนได้เรื่อยๆ มากกว่า 1 ครั้ง เราจะใช้ StreamBuilder เช่นการกดปุ่มที่กดได้มากกว่า 1 ครั้ง&lt;/p&gt;

&lt;p&gt;&lt;em&gt;แน่นอนว่าเราสามารถใช้ StreamBuilder แทน FutureBuilder ได้แทบจะทุกกรณีเลย&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ทีนี้ลองเอา StreamBuilder มาใช้กับโค้ด Counter ดูบ้าง&lt;/p&gt;

&lt;p&gt;ในเคสนี้ เราเปลี่ยน Text ตรงที่แสดงตัวนับให้กลายเป็น StreamBuilder จากนั้นสร้าง StreamController ขึ้นมาหนึ่งตัว ซึ่งจะอัพเดทค่า counter แทนการสั่ง &lt;code&gt;setState()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyHomePageState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyHomePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;_incrementCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//แทนที่จะใช้ setState ก็เซ็ตค่าผ่าน StreamController แทน&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;_counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Scaffold'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;columnWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;columnWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Column Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;incrementButtonWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;counterWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;incrementButtonWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Increment Button Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RaisedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;incrementButtonTextWidget&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;_incrementCounter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;incrementButtonTextWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Increment Button Text Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Increment'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;counterWidget&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;StreamBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;stream:&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'render - Counter Widget'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'count is &lt;/span&gt;&lt;span class="si"&gt;${snapshot.data}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ในกรณีนี้วิดเจ็ตทั้งหมดจะมีการเรนเดอร์แค่ครั้งแรกครั้งเดียว หลังจากนั้นถ้ามีการกดปุ่ม วิดเจ็ตตัวอื่นที่ไม่เกี่ยวข้องด้วย จะไม่มีการเรนเดอร์ใหม่ เรนเดอร์เฉพาะตัวของ StreamBuilder เท่านั้น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render - Scaffold
render - Column Widget
render - Increment Button Widget
render - Increment Button Text Widget
render - Counter Widget
render - Counter Widget
render - Counter Widget
render - Counter Widget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จะเห็นว่าวิธีนี้ทำให้ประสิทธิภาพของแอพเพิ่มขึ้นเยอะมาก เพราะไม่จำเป็นต้องเรนเดอร์ทั้งหน้าใหม่ทุกครั้งที่มีข้อมูลเปลี่ยนแปลงเพียงเล็กน้อย&lt;/p&gt;

&lt;p&gt;ซึ่งก็แลกมากับการที่เราต้องเขียนโค้ดเยอะขึ้นล่ะนะ (ฮา)&lt;/p&gt;

&lt;h2&gt;
  
  
  AsyncSnapshot
&lt;/h2&gt;

&lt;p&gt;ในการใช้ทั้ง FutureBuilder และ StreamBuilder จะมีสิ่งที่เรียกว่า &lt;strong&gt;AsyncSnapshot&lt;/strong&gt; ส่งมาให้ตัว เจ้าตัวนี้เป็นเหมือนกับตัวที่บอกว่าตอนนี้ข้อมูลของเรามีสถานะเป็นยังไงบ้างแล้ว&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// สถานะของ future/stream ในตอนนั้น&lt;/span&gt;
&lt;span class="n"&gt;snapshort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connectionState&lt;/span&gt;

&lt;span class="c1"&gt;// มี error เกิดขึ้นไหม&lt;/span&gt;
&lt;span class="n"&gt;snapshop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasError&lt;/span&gt;
&lt;span class="c1"&gt;// error คืออะไร&lt;/span&gt;
&lt;span class="n"&gt;snapshop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;

&lt;span class="c1"&gt;// ได้รับ data มาแล้วรึยัง&lt;/span&gt;
&lt;span class="n"&gt;snapshop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasData&lt;/span&gt;
&lt;span class="c1"&gt;// data คืออะไร&lt;/span&gt;
&lt;span class="n"&gt;snapshop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ConnectionState
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;สำหรับ Future&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;waiting&lt;/code&gt;: ขณะกำลังรอข้อมูล&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;done&lt;/code&gt;: เมื่อได้รับข้อมูลมาแล้ว&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;สำหรับ Stream&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;waiting&lt;/code&gt;: ขณะกำลังรอข้อมูล&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;active&lt;/code&gt;: เมื่อได้รับข้อมูลมาแล้ว แต่ stream ยังไม่ &lt;code&gt;close&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;done&lt;/code&gt;: เมื่อสั่งให้ stream &lt;code&gt;close&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AsyncSnapshot&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// เช็กก่อนว่ามี error มั้ย&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'เกิดข้อผิดพลาดในการโหลดข้อมูล &lt;/span&gt;&lt;span class="si"&gt;${snapshot.error}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ถ้าไม่มี ตอนนี้โหลดข้อมูลเป็นยังไงบ้างแล้ว&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;connectionState&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="c1"&gt;// ข้อมูลยังไม่มา กำลังโหลดอยู่&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ConnectionState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;waiting&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'กำลังโหลดข้อมูลอยู่'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// ข้อมูลมาเรียบร้อยแล้ว แสดงผลได้&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ConnectionState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;done&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;ConnectionState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ข้อมูลคือ &lt;/span&gt;&lt;span class="si"&gt;${snapshot.data}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ทิ้งท้าย...
&lt;/h2&gt;

&lt;p&gt;การใช้ FutureBuilder / StreamBuilder ใน Flutter เป็นสิ่งที่ช่วยเพิ่มประสิทธิภาพให้ตัวแอพไม่ต้องเรนเดอร์วิดเจ็ตที่ไม่ได้เปลี่ยนแปลงซ้ำๆ&lt;/p&gt;

&lt;p&gt;ซึ่งคอนเซ็ปนี้จะถูกเอาไปใช้ต่อในแพทเทิร์นที่ทาง Google แนะนำมาให้ใช้กับการวางโครงสร้าง UI ใน Flutter ที่ชื่อว่า &lt;strong&gt;BLoC&lt;/strong&gt; หรือ &lt;strong&gt;Business Logic Component&lt;/strong&gt; ซึ่งเดี๋ยวเราจะเอามาสอนกันต่อในบทความซีรีส์ Flutter ต่อไป&lt;/p&gt;

&lt;p&gt;ส่วนบทความซีรีส์ Async in Dart ก็ขอจบลงแค่ตอนนี้ก่อนล่ะ&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>dart</category>
      <category>flutter</category>
    </item>
    <item>
      <title>Dependency Injection กับ Service Locator ต่างกันยังไงนะ?</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Tue, 09 Jun 2020 15:44:57 +0000</pubDate>
      <link>https://dev.to/tamemo/dependency-injection-service-locator-1j0h</link>
      <guid>https://dev.to/tamemo/dependency-injection-service-locator-1j0h</guid>
      <description>&lt;p&gt;ในโลกของ OOP เรามักจะสร้างคลาสต่างๆ ที่มีการเรียกใช้กันต่อเป็นทอดๆ มากมาย&lt;/p&gt;

&lt;p&gt;เช่นโค้ดข้างล่างนี่&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราสร้างคลาส &lt;code&gt;Car&lt;/code&gt; และ &lt;code&gt;Engine&lt;/code&gt; คือ&lt;strong&gt;รถ&lt;/strong&gt;และ&lt;strong&gt;เครื่องยนต์&lt;/strong&gt;ขึ้นมา โดยการจะสร้างรถได้ เราจะต้องสร้างเครื่องยนต์ขึ้นมาด้วย&lt;/p&gt;

&lt;p&gt;ในกรณีแบบนี้เราเรียกว่าคลาส &lt;code&gt;Car&lt;/code&gt; depend on &lt;code&gt;Engine&lt;/code&gt; (Car ต้องการ Engine) หรือแปลว่า &lt;em&gt;เราไม่สามารถสร้างคลาส Car ได้ถ้าไม่มีคลาส Engine&lt;/em&gt; หรือ &lt;em&gt;Engine นั้นเป็น "Dependency" ของคลาส Car&lt;/em&gt; นั่นเอง&lt;/p&gt;

&lt;p&gt;แต่ตามหลักการออกแบบ OOP แล้วเราไม่ควรเขียนแบบโค้ดด้านบน &lt;strong&gt;คือไม่ควร &lt;code&gt;new&lt;/code&gt; อ็อบเจคตรงๆ ในคลาสอื่น เพราะจะทำให้เราเปลี่ยนแปลงพฤติกรรมต่างๆ ของโค้ดทำได้ยาก&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;เช่นถ้าเราต้องการจะเปลี่ยน Engine ไปเป็น EcoEngine เครื่องยนต์แบบอีโค่เราจะต้องแก้โค้ดในคลาส Car เท่านั้น&lt;/p&gt;

&lt;p&gt;วิธีการแก้แบบมาตราฐานก็คือถ้าเราต้องการใช้อ็อบเจคจากคลาสอื่น อย่าnewเอง แต่ให้รับอ็อบเจคเข้ามาแทน อาจจะทาง constructure แบบนี้ก็ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่สำหรับมือใหม่หัดเขียน OOP นั้นมักจะไม่เขียนโค้ดในแพทเทิร์นแบบนี้ ด้วยเหตุผลว่าเวลาเราจะสร้าง Car ขึ้นมาใช้นั้น จะต้องไปสร้าง Dependencies ทั้งหมดของ Car ขึ้นมาซะก่อน (คือ new ตรงๆ ทันทีไม่ได้นั่นแหละ)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ถ้ามี Dependencies ไม่เยอะก็ยังไม่เท่าไหร่ แต่ถ้าเยอะๆ นี่ก็มีความปวดหัวเหมือนกัน&lt;/p&gt;

&lt;p&gt;เช่น ถ้าเราต้องการสร้างบ้านขึ้นมา แต่บ้านก็ต้องมี ประตู หน้าต่าง กำแพง บลาๆๆ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Door&lt;/span&gt; &lt;span class="n"&gt;door&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Door&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Window&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Window&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Wall&lt;/span&gt; &lt;span class="n"&gt;wall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Wall&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Ceil&lt;/span&gt; &lt;span class="n"&gt;ceil&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Ceil&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Floor&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Floor&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;House&lt;/span&gt; &lt;span class="n"&gt;house&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;House&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;door&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wall&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ceil&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;floor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่งถ้าเราย้ายโค้ดพวกนี้เข้าไปไว้ในคลาส การจะสร้าง &lt;code&gt;House&lt;/code&gt; ขึ้นมาก็จะเหลือแค่นี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;House&lt;/span&gt; &lt;span class="n"&gt;house&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;House&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DI Service แบบคร่าวๆ
&lt;/h2&gt;

&lt;p&gt;หลักการ DI (หรือ Dependency Injection) แบบคร่าวๆ คือเราจะไม่ new อ็อบเจคในคลาสแบบที่เล่าไปข้างต้น แต่เพราะวิธีการนี้มันยุ่งยากกว่า คนส่วนใหญ่เลยชอบสร้างคลาสกันแบบ new ตรงๆ ในคลาสเลย ไม่ทำการรับอ็อบเจคเข้ามาทาง Constructure&lt;/p&gt;

&lt;p&gt;ดังนั้นเลยมีคนเห็นปัญหานี้ ในเมื่อ DI เป็นคอนเซ็ปที่ดี แต่เขียนยุ่งยากมาก ... จะดีกว่าถ้าเราสามารถสร้างอ็อบเจคที่มี dependencies เต็มไปหมดด้วยการสั่ง new ง่ายๆ&lt;/p&gt;

&lt;p&gt;DI Service คือตัวช่วยที่ว่า ซึ่งเป็นเหมือนตัวที่จะคอยจัดการและสร้างอ็อบเจคให้เราแทน&lt;/p&gt;

&lt;p&gt;ซึ่งการใช้งานส่วนใหญ่จะแบ่งออกเป็น 2 เฟส นั่นคือการกำหนดค่าว่า Dependencies แต่ละตัวมีวิธีสร้างยังไง หลังจากนั้นคือการสั่งให้มันสร้างอ็อบเจคกลับมาให้เรา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Setup&lt;/span&gt;
&lt;span class="nc"&gt;DIService&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Create Object&lt;/span&gt;
&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แต่เอาจริงๆ บางครั้ง ในบางภาษา การจะใช้งาน DI Service พวกนี้ก็ยุ่งยากกว่าการสร้างเองตรงๆ ซะดี (ฮา) ตัวอย่างเช่น &lt;strong&gt;&lt;a href="https://dagger.dev/" rel="noopener noreferrer"&gt;Dagger2&lt;/a&gt;&lt;/strong&gt; สำหรับภาษา Java &lt;/p&gt;

&lt;h2&gt;
  
  
  แต่..เอ๊ะ! นี่มัน Service Locator ตั้งหาก
&lt;/h2&gt;

&lt;p&gt;ในบางภาษา หากเราเสิร์จหา library เพื่อมาช่วยเราทำ DI Service เราอาจจะเจอตัวที่ใช้แพทเทิร์นแบบ Container&lt;/p&gt;

&lt;p&gt;แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;นั่นคือ แทนที่จะรับอ็อบเจคเข้ามาผ่าน Constructure ตรงๆ แต่จะใช้วิธีการขอจากสิ่งที่เรียกว่า &lt;strong&gt;Container&lt;/strong&gt; แทน (ไม่ได้ new เองนะ แต่ขออ็อบเจคมาจากคอนเทนเนอร์)&lt;/p&gt;

&lt;p&gt;วิธีใช้งานก็คล้ายๆ กับ DI Service นั่นแหละ คือต้องทำการกำหนดค่า dependencies ซะก่อน แล้วถึงจะเรียกใช้งานได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Setup&lt;/span&gt;
&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Create Object&lt;/span&gt;
&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เอาล่ะ! ถึงผลลัพธ์จะออกมาเหมือนกันเป๊ะ! แถมคนส่วนใหญ่ยังเรียกวิธีการทั้ง 2 ตัวนี้ว่า DI ทั้งคู่อีกตั้งหาก&lt;/p&gt;

&lt;p&gt;แต่เนื่องจากโค้ดมันเขียนไม่เหมือนกัน ดังนั้นเขาเลยตั้งชื่อแยกมันออกเป็น 2 แพทเทิร์น นั่นคือ &lt;strong&gt;"Dependency Injection"&lt;/strong&gt; และ &lt;strong&gt;"Service Locator"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-xic2kR5nn_w%2FXt5pepWJpoI%2FAAAAAAAASa8%2F6HWT5yydf-8dRcJCgXpegPE6VDQ6Vg0zQCNcBGAsYHQ%2Fs1600%2Fdi-vs-service-locator.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-xic2kR5nn_w%2FXt5pepWJpoI%2FAAAAAAAASa8%2F6HWT5yydf-8dRcJCgXpegPE6VDQ6Vg0zQCNcBGAsYHQ%2Fs1600%2Fdi-vs-service-locator.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ข้อแตกต่างล่ะ?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Service Locator
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;คอนเซ็ปคือคลาสเป้าหมาย ขออ็อบเจคจาก Service Locator ซึ่งจะไปตามหามาให้&lt;/li&gt;
&lt;li&gt;คลาสเป้าหมายเรียกใช้ Service Locator&lt;/li&gt;
&lt;li&gt;มีสิ่งที่เรียกว่า Container สำหรับเก็บอ็อบเจค&lt;/li&gt;
&lt;li&gt;คลาสจะขออ็อบเจคจาก Container แทนการ new ขึ้นมาเอง&lt;/li&gt;
&lt;li&gt;ใช้งานและเข้าใจได้ง่าย เพราะอยากได้อ็อบเจคอะไรก็ขอเอาจาก Container ตรงๆ ได้เลย (ส่วนใหญ่ Container จะเป็นแบบ static คือเรียกจากตรงไหนในโปรแกรมเราก็ได้)&lt;/li&gt;
&lt;li&gt;ปัญหาคือมันจะทำให้มี dependency เพิ่มขึ้นมาในระบบเราอีก 1 ตัวคือ Container นั่นแหละ แถมคลาสแทบทุกคลาสในระบบเรายัง depend on เจ้าคอนเทนเนอร์นี้ซะอีก&lt;/li&gt;
&lt;li&gt;ถ้าเกิดอยากเปลี่ยน library สำหรับทำ Service Locator จะต้องแก้โค้ดแทบจะทั้งโปรแกรม!&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Dependency Injection
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;คอนเซ็ปคือ DI Service จะเช็กดูว่าคลาสเป้าหมาย เวลาจะสร้างต้องการ dependencies อะไรไป ก็จะไปหามาให้ แล้วเอาไป new อ็อบเจคเป้าหมายขึ้นมา&lt;/li&gt;
&lt;li&gt;คลาสเป้าหมายไม่ได้เรียกใช้ DI Service, แต่ DI Service เป็นฝ่ายที่จะ new อ็อบเจคขึ้นมาเอง &lt;/li&gt;
&lt;li&gt;ใช้วิธี inject อ็อบเจคเข้าไปตรงๆ &lt;/li&gt;
&lt;li&gt;สำหรับคลาสเป้าหมายจะไม่ต้องเปลี่ยนอะไรมากนัก เพราะ dependencies ทั้งหมดถูกส่งเข้ามาทาง Constructure อยู่แล้ว&lt;/li&gt;
&lt;li&gt;เขียนเทสได้ง่ายโดยการสร้าง mock dependencies ขึ้นมาเองไม่ต้องผ่าน DI Service เลยก็ยังได้&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  เขียนเทสยังไง?
&lt;/h2&gt;

&lt;p&gt;จริงๆ เป้าหมายของการทำ DI ทั้งหมดคือเพื่อเอามาเขียนเทสหรือการทดสอบโปรแกรมได้ง่ายๆ นะ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;testCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TestEngine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่งในเคสนี้ Service Locator จะ mock อ็อบเจคต่างๆ ได้ยากมากเพราะเป็นการเรียกใช้งานแบบ static คือเรียกตรงๆ ที่ Container ในคลาสเลย&lt;/p&gt;

&lt;p&gt;ดังนั้นคำแนะนำสำหรับคนใช้แพทเทิร์น Service Locator คืออย่าเรียก Container ตรงๆ แต่ให้ inject Container นี้เข้าไปแทน&lt;/p&gt;

&lt;p&gt;แบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เพราะจะทำให้เราสร้าง container สำหรับเทสอ็อบเจคขึ้นมาได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Develop&lt;/span&gt;
&lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Testing&lt;/span&gt;
&lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="n"&gt;testContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;testContainer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TestEngine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="n"&gt;testCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testContainer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>programming</category>
      <category>learning</category>
      <category>tips</category>
      <category>oop</category>
    </item>
    <item>
      <title>Async in Dart (4) ควบคุมข้อมูลในstreamอย่างเหนือชั้นด้วย StreamController</title>
      <dc:creator>Ta</dc:creator>
      <pubDate>Sat, 30 May 2020 17:07:01 +0000</pubDate>
      <link>https://dev.to/tamemo/async-in-dart-4-stream-streamcontroller-4dn2</link>
      <guid>https://dev.to/tamemo/async-in-dart-4-stream-streamcontroller-4dn2</guid>
      <description>&lt;p&gt;ในบทที่แล้วเราสอนการสร้าง Stream แบบง่ายๆ ไปแล้ว แต่ในบางครั้งเราต้องการควบคุมข้อมูลใน Stream แบบคัสตอมมากๆ ซึ่งข้อมูลอาจจะเข้ามาจากหลายทางมากๆ การที่เรามีแค่ &lt;code&gt;yield&lt;/code&gt; จากฟังก์ชันเดียวอาจจะไม่เพียงพอ&lt;/p&gt;

&lt;p&gt;ดังนั้นเลยเป็นที่มาของคลาสที่ชื่อว่า &lt;code&gt;StreamController&lt;/code&gt; ซึ่งเป็นคลาสที่เอาไว้ควบคุม &lt;code&gt;Stream&lt;/code&gt; อีกที&lt;/p&gt;

&lt;h2&gt;
  
  
  StreamController
&lt;/h2&gt;

&lt;p&gt;การสร้าง Stream แบบธรรมดาก็จะเป็นประมาณนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getNumberStream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numberStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getNumberStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ส่วนใหญ่เราจะสร้าง Stream จากฟังก์ชันประเภท &lt;code&gt;async*&lt;/code&gt; ซึ่งภายในฟังก์ชันก็จะมีการ &lt;code&gt;yield&lt;/code&gt; ข้อมูลกลับมา&lt;/p&gt;

&lt;p&gt;ทีนี้ ถ้าเราจะเปลี่ยนไปใช้ StreamController แทน ก็จะเป็นแบบนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;นั่นคือ จากปกติที่เราจะสร้างข้อมูลในฟังก์ชันเท่านั้น การสร้างด้วย StreamController คือเราไม่ต้องกำหนดว่า Stream ตัวนี้จะสร้างอะไรเลย (แค่ new ตัวคอนโทรเลอร์ขึ้นมาเฉยๆ ก็พอแล้ว)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;StreamController ไม่ใช่ Stream นะ ไม่สามารถเอาไปใช้แทน Stream ได้ แต่สามารถดึง Stream ออกมาจากตัวมันได้&lt;/p&gt;

&lt;p&gt;ให้คิดง่ายๆ ว่ามันคือ Controller ที่ถือ Stream เอาไว้ข้างในอีกทีก็ได้&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;สำหรับอ็อบเจค StreamController ที่เราสร้างขึ้นมา จะมี Stream อยู่ข้างใน เราสามารถดึงออกมาใช้งานได้ด้วยการสั่ง &lt;code&gt;.stream&lt;/code&gt; ตรงๆ เลย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'value: &lt;/span&gt;&lt;span class="si"&gt;$value&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//หรือ&lt;/span&gt;

&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'value: &lt;/span&gt;&lt;span class="si"&gt;$value&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  แล้วข้อมูลจะมาจากไหน? ใช้คำสั่ง add ยังไงล่ะ
&lt;/h2&gt;

&lt;p&gt;StreamController นั้นไม่ได้เป็นฟังก์ชัน ดังนั้นมันจะไม่มีโลจิคการสร้างข้อมูลอะไรอยู่กับตัวมันทั้งนั้น!&lt;/p&gt;

&lt;p&gt;StreamController เป็นแค่ตัวกลางสำหรับใส่ข้อมูลเข้า Stream เท่านั้น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:async'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addNumberToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;จากโค้ดด้านบน เรามีการสร้าง StreamController ขึ้นมา 1 ตัว แล้วจัดการ &lt;code&gt;listen()&lt;/code&gt; มันใน main (listen ไว้ก่อน ยังไม่มีข้อมูลอะไรเข้ามาทั้งนั้น)&lt;/p&gt;

&lt;p&gt;ทีนี้ เราก็ไปสร้างฟังก์ชันอีกตัวหนึ่งชื่อ &lt;code&gt;addNumberToStream(int x)&lt;/code&gt; ซึ่งจะมีการเพิ่มค่าเข้า Stream ผ่านคำสั่ง &lt;code&gt;add()&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;เมื่อฟังก์ชัน &lt;code&gt;addNumberToStream(int x)&lt;/code&gt; ถูกเรียก StreamController ก็จะส่งค่านั้นไปให้ listener ที่รอค่าอยู่นั่นเอง&lt;/p&gt;

&lt;p&gt;เราสามารถส่งข้อมูลกี่ครั้งก็ได้ผ่านคำสั่ง &lt;code&gt;add()&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;ส่วนใหญ่ use case ที่เราต้องใช้ StreamController แทนการสร้างฟังก์ชัน async* แบบธรรมดาจะเป็นการเขียนโปรแกรมแบบ &lt;strong&gt;Event-Driving&lt;/strong&gt; เพราะเราไม่รู้ว่าข้อมูลจะเข้ามาเมื่อไหร่ ตอนไหนที่ผู้ใช้จะกดปุ่ม อะไรแบบนั้น เราเลยสร้างฟังก์ชันเตรียมไว้ก่อนไม่ได้ ทำได้แค่ให้ controller คอยส่งข้อมูลมาให้เมื่อเกิด Event เท่านั้น&lt;/p&gt;

&lt;h3&gt;
  
  
  คำเตือน! StreamController มักจะไม่รู้จุดสิ้นสุด!
&lt;/h3&gt;

&lt;p&gt;การใช้งาน Stream ธรรมดา เราสามารถเปลี่ยนจากการใช้ callback ด้วย &lt;code&gt;listen()&lt;/code&gt; ไปใช้ &lt;code&gt;await&lt;/code&gt; เพื่อเปลี่ยนโค้ดให้อยู่ในรูปแบบ sync แทนได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numberStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getNumberStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numberStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Receive: &lt;/span&gt;&lt;span class="si"&gt;$number&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ซึ่งมีข้อควรระวังในการใช้ &lt;code&gt;await&lt;/code&gt; คือ &lt;strong&gt;Stream ตัวนั้นจะต้องเป็น "Finite Stream" หรือสตรีมที่รู้ว่ามีจุดสิ้นสุดแน่ๆ !&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ไม่งั้นโค้ดของเราจะถูก &lt;code&gt;await&lt;/code&gt; บล็อกการทำงานอยู่ที่ลูปนั้น ไปต่อไม่ได้ เช่น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:async'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'start'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'clicked!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'end'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ในกรณีแบบนี้ โค้ดจะถูกบล็อกอยู่ที่ลูป (โปรแกรมจะไม่หลุดไปยังคำสั่งปริ้น end เลย) เพราะไม่มีการปิดสตรีม&lt;/p&gt;

&lt;p&gt;ดังนั้นถ้าฟังก์ชันเรามีคำสั่งให้ทำอะไรบ้างอย่างต่อไป เราไม่ควรเขียนมันในรูป &lt;code&gt;await&lt;/code&gt; นะ ใช้ &lt;code&gt;listen()&lt;/code&gt; จะดีกว่า&lt;/p&gt;

&lt;h2&gt;
  
  
  ยังมี addError และ close อีกนะ
&lt;/h2&gt;

&lt;p&gt;นอกจากการ add ข้อมูลเข้า Stream แล้วเรายังสามารถสั่งอีก 2 คำสั่งกับคอรโทรเลอร์ได้ คือการโยน Exception หรือสั่งปิด Stream นั่นเอง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:async'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;onDone:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'จบแล้วจ้า!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'error is &lt;/span&gt;&lt;span class="si"&gt;$e&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;cancelOnError:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'start'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'ตู้มมม'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'end'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start
end
1
2
3
error is Exception: ตู้มมม
4
5
จบแล้วจ้า!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;การสั่ง &lt;code&gt;addError&lt;/code&gt; ไม่ได้ทำให้ Stream หยุดทำงานนะ ไม่งั้นต้องเพิ่มอ็อบชัน &lt;code&gt;cancelOnError: true&lt;/code&gt; ลงไปด้วย (ถ้าไม่เซ็ต ดีฟอลต์จะเป็น &lt;code&gt;false&lt;/code&gt; คือถึงเจอ Exception ฉันก็ไม่หยุดนะ)&lt;/p&gt;

&lt;p&gt;ข้อสังเกตอีกอย่างคือ &lt;code&gt;listen()&lt;/code&gt; นั้นเป็น &lt;strong&gt;Isolates&lt;/strong&gt; นะ มันจะปริ้น &lt;strong&gt;start&lt;/strong&gt; และ &lt;strong&gt;end&lt;/strong&gt; (อยู่ใน Isolates ของ ฟังก์ชัน main) ก่อน&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ใครงงว่า Isolates คืออะไร ย้อนกลับไปอ่านบทความแรกของซีรีส์นี้อีกทีนะ&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;สุดท้าย การใช้งาน StreamController นั้นมีอีกเรื่องที่ต้องระวัง คือ...&lt;/p&gt;

&lt;h2&gt;
  
  
  Stream อาจจะไม่ได้ถูก subscription ในทันที
&lt;/h2&gt;

&lt;p&gt;ลองดูตัวอย่างโค้ดนี้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counter1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;periodic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;maxCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เราตั้งให้ฟังก์ชัน &lt;code&gt;counter1&lt;/code&gt; ทำการ add ตัวเลขเข้าไปเรื่อยๆ ทุกๆ 1 วินาที (ฟังก์ชัน &lt;code&gt;Timer.periodic()&lt;/code&gt; เอาไว้สำหรับสั่งงานที่ทำงานซ้ๆ กันทุกๆ ช่วงเวลาหนึ่ง คล้ายๆ กับ &lt;code&gt;setInterval&lt;/code&gt; ใน JavaScript)&lt;/p&gt;

&lt;p&gt;เวลาใช้งาน ก็ใช้ &lt;code&gt;listen()&lt;/code&gt; ตามปกติหรือใช้ for loop แล้วเติม &lt;code&gt;await&lt;/code&gt; ลงไปก็ได้&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//start!&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;counterStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;counter1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;//listen&lt;/span&gt;
    &lt;span class="n"&gt;counterStream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;แบบนี้ถ้าเอาไปรัน ก็จะได้ output เป็นเลข 1, 2, 3, 4, 5 ตัวใน 5 วินาที ... อันนี้มาตราฐาน ตามคอมมอนเซ้นส์ ไม่มีอะไรแปลก&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;แต่ถ้าเรามีการสั่ง delay ก่อนที่เราจะ &lt;code&gt;listen()&lt;/code&gt; แบบนี้&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//start!&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;counterStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;counter1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;//waiting 2 sec.&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delayed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;//listen&lt;/span&gt;
    &lt;span class="n"&gt;counterStream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;คำถามคือถ้าเขียนโค้ดแบบนี้ เราคาดหวังว่า output จะเป็นยังไง?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;โปรแกรมก็น่าจะหยุดรอ 2 วินาที&lt;/li&gt;
&lt;li&gt;แล้วก็ค่อยๆ ปริ้นเลข 1, 2, 3, 4, 5 ทีละวิ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;แต่มันไม่ใช่แบบนั้นน่ะสิ!&lt;/p&gt;

&lt;p&gt;การทำงานของโปรแกรมคือหลังจาก delay 2 วินาทีแล้ว มันจะทำการปริ้นเลข 1, 2 ออกมาในทันที (ดูรูปข้างล่างประกอบนะ)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-uwwhD-6l3PQ%2FXs_mr4-gqOI%2FAAAAAAAASYo%2FrTre6jL4gNoRGBKUdw_JB5NXD2PzVRd_wCNcBGAsYHQ%2Fs1600%2Fdart-async-4-01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F3.bp.blogspot.com%2F-uwwhD-6l3PQ%2FXs_mr4-gqOI%2FAAAAAAAASYo%2FrTre6jL4gNoRGBKUdw_JB5NXD2PzVRd_wCNcBGAsYHQ%2Fs1600%2Fdart-async-4-01.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;สำหรับการใช้งาน Stream นั้นมันจะทำงานทันที &lt;strong&gt;แม้ว่าจะยังไม่มีใครมารอ listen มันเลยก็ตาม&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;แบบในเคสนี้ เราเรียกฟังก์ชัน &lt;code&gt;counter1()&lt;/code&gt; ให้ทำงาน แล้วทำการ delay มันซะ 2 วินาทีแล้วค่อย listen แต่ตัว counter นั้นดันทำงานก่อนไปแล้ว ไม่ได้เริ่มทำงานตอนที่เรา listen &lt;/p&gt;

&lt;p&gt;แต่ถ้าเราต้องการให้มันทำงานเมื่อสั่ง listen จังหวะนั้นเลย (แบบ counter2 ในรูปข้างบน) เราจะต้องเซ็ตค่าตอนสร้าง StreamController&lt;/p&gt;

&lt;p&gt;ในการสร้าง StreamController เราสามารถกำหนดอ็อบชันเพิ่มได้คือ&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;onListen&lt;/li&gt;
&lt;li&gt;onPause&lt;/li&gt;
&lt;li&gt;onResume&lt;/li&gt;
&lt;li&gt;onCancel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;วิธีการก็คือเราจะต้องสร้าง Stream ที่ตอนแรกยังไม่เริ่มนับ counter แล้วสั่งให้มันเริ่มนับตอน &lt;code&gt;onListen&lt;/code&gt; นั่นเอง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counter2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Timer&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;//ฟังก์ชันสำหรับเริ่มรับเลข&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;periodic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;maxCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;//ฟังก์ชันสำหรับหยุดนับเลข&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;

        &lt;span class="c1"&gt;//เริ่มทำงาน startTimer() เมื่อ listen นะ&lt;/span&gt;
        &lt;span class="nl"&gt;onListen:&lt;/span&gt; &lt;span class="n"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="nl"&gt;onPause:&lt;/span&gt; &lt;span class="n"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onResume:&lt;/span&gt; &lt;span class="n"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onCancel:&lt;/span&gt; &lt;span class="n"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>programming</category>
      <category>dart</category>
      <category>flutter</category>
    </item>
  </channel>
</rss>
