<?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: phatsss</title>
    <description>The latest articles on DEV Community by phatsss (@phatsss).</description>
    <link>https://dev.to/phatsss</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%2Fuser%2Fprofile_image%2F859001%2Fc2fcc56e-2aea-403f-bd13-c8e2ab291c84.jpeg</url>
      <title>DEV Community: phatsss</title>
      <link>https://dev.to/phatsss</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phatsss"/>
    <language>en</language>
    <item>
      <title>JavaScript EP7: Promises &amp; Async/Await⏳🪄</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Sat, 06 May 2023 14:10:41 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep7-promises-asyncawait-4nan</link>
      <guid>https://dev.to/phatsss/javascript-ep7-promises-asyncawait-4nan</guid>
      <description>&lt;p&gt;ເຄີຍຮັບມືກັບ JS code ທີ່ແບບວ່າ...ມັນບໍ່ໄດ້ເຮັດວຽກຕາມທີ່ເຮົາຄາດຫວັງໄວ້ບໍ່? ອາດຈະເບິ່ງຄືກັບວ່າ function ຕ່າງໆຖືກ execute ແບບສຸ່ມ-ໝາຍຄວາມວ່າເຮົາບໍ່ສາມາດຄາດເດົາເວລາທີ່ໃຊ້ໃນການ execute ໄດ້ເລີຍ ຫຼື ເກີດເຫດການທີ່ວ່າການ execute ລ່າຊ້າ, ມື້ນີ້ເຮົາຈະມາເບິ່ງ feature ສຸດຄັກທີ່ຊື່ວ່າ &lt;strong&gt;Promises&lt;/strong&gt; ຂອງ JavaScript ນຳກັນ🧙🏻‍♂️.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ຖ້າໃຜຍັງບໍ່ໄດ້ອ່ານ EP1 ທີ່ໄດ້ອະທິບາຍເຖິງການເຮັດວຽກຂອງ Event Loop, ແນະນຳໃຫ້ກັບໄປອ່ານກ່ອນ, ເນື່ອງຈາກມັນເປັນເນື້ອຫາທີ່ກ່ຽວຂ້ອງກັນ.&lt;br&gt;
&lt;a href="https://dev.to/phatsss/javascript-ep1-event-loop-2mop"&gt;JavaScript EP1: Event Loop♻️&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ເມື່ອເຮົາຂຽນ JS ສິ່ງໜຶ່ງທີ່ເຮົາມັກຈະຕ້ອງໄດ້ພົບຢູ່ຕະຫຼອດກໍ່ຄືການຈັດການ tasks ທີ່ມີການເຮັດວຽກກັບ tasks ອື່ນໆ, ສົມມຸດວ່າເຮົາຕ້ອງການທີ່ຈະ get image, compress, ໃສ່ filter ແລະ ບັນທຶກຮູບນັ້ນໆຈະມີຂັ້ນຕອນການເຮັດວຽກດັ່ງນີ້:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ສິ່ງທຳອິດທີ່ເຮົາຈະເຮັດກໍ່ຄືການດຶງເອົາຮູບທີ່ເຮົາຕ້ອງການແກ້ໄຂ(get image), ເຮົາມີ &lt;code&gt;getImage&lt;/code&gt; function ທີ່ຈະເຮັດວຽກໃນສ່ວນນີ້.&lt;/li&gt;
&lt;li&gt;ຫຼັງຈາກໄດ້ຮູບມາແລ້ວຕໍ່ມາຈະເປັນການ resize image ຈະເປັນສ່ວນຂອງ &lt;code&gt;compressImage&lt;/code&gt; function ຮັບໄມ້ຕໍ່.&lt;/li&gt;
&lt;li&gt;ເມື່ອ resize image ສຳເລັດເຮົາຕ້ອງການໃສ່ filter ເຊິ່ງເຮົາມີ &lt;code&gt;applyFilter&lt;/code&gt; function ຮັບໜ້າທີ່ສ່ວນນີ້ໄປ.&lt;/li&gt;
&lt;li&gt;ສຸດທ້າຍແມ່ນຈະເປັນການບັນທຶກຮູບພາບໂດຍໃຊ້ &lt;code&gt;saveImage&lt;/code&gt; function ຖ້າຫາກບໍ່ມີຫຍັງຜິດພາດກໍ່ຈະທຳການແຈ້ງໃຫ້ user ຮູ້ວ່າໄດ້ທຳການບັນທຶກຮູບພາບສຳເລັດ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ສຸດທ້າຍເຮົາຈະໄດ້ code ປະມານນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ct6ywwMl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s---Kv6sJn7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ixceqsql5hpdq8txx43s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ct6ywwMl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s---Kv6sJn7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ixceqsql5hpdq8txx43s.png" alt="getImage function" width="800" height="446"&gt;&lt;/a&gt;&lt;br&gt;
ສັງເກດເຫັນຫຍັງບາງຢ່າງບໍ່? ຮູ້ສຶກວ່າໃນ code ຂອງເຮົາມີການໃຊ້ nested callback functions ຫຼາຍເກີນໄປເຊິ່ງມັນພັດຂຶ້ນກັບ callback ກ່ອນໜ້າອີກ. callback ໃນລັກສະນະນີ້ມັກຖືກເອີ້ນວ່າ callback hell🤯 ເນື່ອງຈາກມັນມີ callback function ຊ້ອນກັນຫຼາຍເກີນໄປຈຶ່ງເຮັດໃຫ້ code ອ່ານຍາກຂຶ້ນໄປອີກ.&lt;/p&gt;

&lt;p&gt;ໂຊກດີທີ່ເຮົາມີສິ່ງທີ່ເອີ້ນວ່າ promises ທີ່ຈະເຂົ້າມາຊ່ວຍເຮົາຈັດການກັບບັນຫາແບບນີ້, ເຮົາໄປທຳຄວາມຮູ້ຈັກກັບ promises ນຳກັນແບບເລິກໆກັນເລີຍ🫡.&lt;/p&gt;




&lt;h3&gt;
  
  
  Promise Syntax
&lt;/h3&gt;

&lt;p&gt;ຖ້າໃຜເຄີຍໄດ້ອ່ານບົດຄວາມ ຫຼື ເອກະສານໃດໆກໍ່ຕາມທີ່ອະທິບາຍກ່ຽວກັບ Promises ກໍ່ອາດຈະຄຸ້ນຕາກັບນິຍາມ ຫຼື ຄຳອະທິບາຍ Promises ປະມານວ່າ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A promise is a placeholder for a value that can either resolve or reject at some time in the future"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ຖ້າຈະເບິ່ງຕາມນິຍາມ ໂດຍສ່ວນຕົວຜູ້ຂຽນເອງກໍ່ຍັງຮູ້ສຶກວ່າມັນຍັງຄຸມເຄືອ ແລະ ບໍ່ຊັດເຈນໃນບາງຈຸດຢູ່, ເພື່ອໃຫ້ເຮົາເຂົ້າໃຈຫຼາຍຂຶ້ນ ເຮົາມາເບິ່ງລັກສະນະການເຮັດວຽກຂອງມັນແທ້ໆເລີຍດີກວ່າ.&lt;br&gt;
ເຮົາສາມາດສ້າງ promise ໂດຍໃຊ້ &lt;code&gt;Promise&lt;/code&gt; constructor ທີ່ມີການຮັບ callback function ດັ່ງນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HNzFjVi_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--phTVdCKA--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/79zi452hphe7ecylhozy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HNzFjVi_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--phTVdCKA--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/79zi452hphe7ecylhozy.gif" alt="promise construtor" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ເຫັນຫຍັງບໍ່ວ່າມີຫຍັງທີ່ຖືກ return ອອກມາ?&lt;br&gt;
&lt;code&gt;Promise&lt;/code&gt; ເປັນ object ໜຶ່ງທີ່ທາງໃນປະກອບມີ &lt;strong&gt;status&lt;/strong&gt;(&lt;code&gt;[[PromiseStatus]]&lt;/code&gt;) ແລະ &lt;strong&gt;value&lt;/strong&gt;(&lt;code&gt;[[PromiseValue]]&lt;/code&gt;). ໃນຕົວຢ່າງດດ້ານເທິງເຮົາຈະເຫັນວ່າ value ຂອງ &lt;code&gt;[[PromiseStatus]]&lt;/code&gt; ແມ່ນ &lt;code&gt;"pending"&lt;/code&gt; ແລະ value ຂອງ promise ແມ່ນ &lt;code&gt;undefined&lt;/code&gt;.&lt;br&gt;
ແຕ່ບໍ່ຕ້ອງຫ່ວງ, ເຮົາບໍ່ໄດ້ເຮັດຫຍັງກັບ object ນີ້ດອກ. ໃນຄວາມເປັນຈິງເຮົາບໍ່ສາມາດ access &lt;code&gt;[[PromiseStatus]]&lt;/code&gt; ແລະ &lt;code&gt;[[PromiseValue]]&lt;/code&gt; properties ໄດ້, ແຕ່ value ຂອງທັງ 2 properties ນີ້ແມ່ນສຳຄັນຫຼາຍເມື່ອເຮົາໃຊ້ promise.&lt;/p&gt;




&lt;p&gt;value ຂອງ &lt;code&gt;PromiseStatus&lt;/code&gt; ຫຼື &lt;strong&gt;state&lt;/strong&gt; ສາມາດເປັນ 1 ໃນ 3 values ດັ່ງນີ້:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;code&gt;fulfilled&lt;/code&gt;: promise ໄດ້ທຳການ &lt;code&gt;resolved&lt;/code&gt; ໝາຍຄວາມວ່າທຸກຢ່າງເຮັດວຽກໄດ້ສຳເລັດ, ບໍ່ມີ error ໃດໆເກີດຂຶ້ນໃນ promise.&lt;/li&gt;
&lt;li&gt;❌ &lt;code&gt;rejected&lt;/code&gt;: promise ໄດ້ທຳການ &lt;code&gt;rejected&lt;/code&gt; ໝາຍຄວາມວ່າມີບາງຢ່າງຜິດພາດ ຫຼື ອາດຈະເກີດ error ຫຍັງບາງຢ່າງໃນ promise.&lt;/li&gt;
&lt;li&gt;⏳ &lt;code&gt;pending&lt;/code&gt;: promise ຍັງບໍ່ມີການ &lt;code&gt;resolved&lt;/code&gt; ແລະ ໃນຂະນະດຽວກັນກໍ່ຍັງບໍ່ &lt;code&gt;rejected&lt;/code&gt; ເຊັ່ນກັນ, ເຊິ່ງມັນຍັງ &lt;code&gt;pending&lt;/code&gt; ຢູ່.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ແລ້ວຕອນໃດທີ່ promise status ຈະເປັນ &lt;code&gt;"pending"&lt;/code&gt;, &lt;code&gt;"fulfilled"&lt;/code&gt; ຫຼື &lt;code&gt;"rejected"&lt;/code&gt;? ແລະ ສະຖານະຂອງ promise ມັນສຳຄັນຈັ່ງໃດ?&lt;/p&gt;

&lt;p&gt;ໃນຕົວຢ່າງດ້ານເທິງເຮົາໄດ້ທຳການ pass callback function &lt;code&gt;() =&amp;gt; {}&lt;/code&gt; ເຂົ້າໄປໃນ &lt;code&gt;promise&lt;/code&gt; constructor. ແຕ່ໃນ callback function ຈະມີການຮັບອີກ 2 arguments, ເຊິ່ງ value ຂອງ argument ທຳອິດເອີ້ນວ່າ &lt;code&gt;resolve&lt;/code&gt; ຫຼື &lt;code&gt;res&lt;/code&gt; ເປັນ method ທີ່ຈະຖືກເອີ້ນເມື່ອ Promise ທຳການ &lt;strong&gt;resolve&lt;/strong&gt; ແລະ &lt;br&gt;
argument ທີ 2 ເອີ້ນວ່າ &lt;code&gt;reject&lt;/code&gt; ແລະ &lt;code&gt;rej&lt;/code&gt; ເປັນ method ທີ່ຈະຖືກເອີ້ນຕອນທີ່ Promise ທຳການ &lt;strong&gt;reject&lt;/strong&gt; ຫຼື ມີບາງຢາດຜິດພາດ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cHp9xS09--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--9A_mOYMP--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/duen4peq0bdr55cka5ya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cHp9xS09--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--9A_mOYMP--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/duen4peq0bdr55cka5ya.png" alt="callback arguments" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ມາເບິ່ງກັນວ່າເມື່ອເຮົາເອີ້ນໃຊ້ &lt;code&gt;resolve&lt;/code&gt; ຫຼື &lt;code&gt;reject&lt;/code&gt; method ຈະໄດ້ຜົນລັບແນວໃດ:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i3r3vxzc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--qKIq-sYt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z0b9v0h7aiq073l5tl2l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3r3vxzc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--qKIq-sYt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z0b9v0h7aiq073l5tl2l.gif" alt="call resolve and reject method" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ໃນທີ່ສຸດເຮົາກໍ່ຮູ້ວິທີທີ່ເຮັດໃຫ້ promise status ບໍ່ເກີດສະຖານະ &lt;code&gt;"pending"&lt;/code&gt; ແລະ &lt;code&gt;undefined&lt;/code&gt; value. &lt;strong&gt;status&lt;/strong&gt; ຂອງ promise ຈະເປັນ &lt;code&gt;"fulfilled"&lt;/code&gt; ຖ້າເຮົາເອີ້ນໃຊ້ &lt;code&gt;resolve&lt;/code&gt; method ແລະ status ຈະເປັນ &lt;code&gt;"rejected"&lt;/code&gt; ຖ້າເຮົາເອີ້ນໃຊ້ &lt;code&gt;rejected&lt;/code&gt; method.&lt;br&gt;
ລອງມາເບິ່ງໃນສ່ວນຂອງ &lt;strong&gt;value&lt;/strong&gt; ຂອງ promise ກັນຕື່ມ, ເຊິ່ງ value ຂອງ &lt;code&gt;[[PromiseValue]]&lt;/code&gt; ຈະເປັນ value ທີ່ເຮົາ pass ເຂົ້າໄປໃນ &lt;code&gt;resolved&lt;/code&gt; ຫຼື &lt;code&gt;rejected&lt;/code&gt; method ໃນຮູບແບບຂອງ argument ຂອງມັນ.&lt;/p&gt;




&lt;p&gt;ມາຮອດຕອນນີ້ເຮົາພໍຈະຮູ້ວິທີຈັດການກັບ Promise object ໃນລະດັບໜຶ່ງແລ້ວ, ຄຳຖາມຕໍ່ມາກໍ່ຄື ມັນໃຊ້ໄວ້ເພື່ອຫຍັງ?🧐.&lt;/p&gt;

&lt;p&gt;ໃນຕົວຢ່າງແລກໆແມ່ນເຮົາໄດ້ເຫັນຕົວຢ່າງທີ່ເຮົາໄດ້ທຳການ get image, compress, ໃສ່ filter ແລະ ບັນທຶກຮູບພາບກັນໄປແລ້ວ, ສຸດທ້າຍເຮົາກໍ່ໄດ້ code ທີ່ມີ nasted callback function ແບບເບິ້ມໆມາຊຸດໜຶ່ງ.&lt;/p&gt;

&lt;p&gt;Promise ກໍ່ສາມາດນຳມາແກ້ບັນຫາທີ່ວ່າມາໄດ້ເຊັ່ນກັນ, ແຕ່ກ່ອນອື່ນໝົດເຮົາຕ້ອງໄດ້ທຳການຂຽນ code ໃໝ່, ເຊິ່ງເຮົາຈະໃຫ້ແຕ່ລະ function ທຳການ return Promise ແທນ.&lt;br&gt;
ຖ້າຫາກໂຫຼດຮູບສຳເລັດ ແລະ ທຸກຢ່າງເຮັດວຽກໂດຍທີ່ບໍ່ມີ error ໃດໆ, ເຮົາຈະທຳການ &lt;strong&gt;resolve&lt;/strong&gt; promise ດ້ວຍໄຟລ໌ທີ່ຖືກໂຫຼດມາແລ້ວ ໃນທີ່ນີ້ຈະເປັນ image ແລະ ຖ້າຫາກເກີດ error ໃນຂະນະທີ່ທຳການໂຫຼດໄຟລ໌ ເຮົາຈະທຳການ &lt;strong&gt;reject&lt;/strong&gt; promise ດ້ວຍການໂຍນ error ອອກມາແທນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nL9-_Y9t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--r9xngcNz--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iebp0rzfnfqsrmmjplme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nL9-_Y9t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--r9xngcNz--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iebp0rzfnfqsrmmjplme.png" alt="getImage return promise" width="800" height="538"&gt;&lt;/a&gt;&lt;br&gt;
ເມື່ອເຮົາລອງສັ່ງ run code ດັ່ງກ່າວຈະໄດ້ຜົນລັບດັ່ງນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z_V8ONBJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uERkfSWf--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsu5nn26dp4elcwh764m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_V8ONBJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uERkfSWf--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsu5nn26dp4elcwh764m.gif" alt="result of getImage return promise" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຈະເຫັນວ່າ Promise ໄດ້ທຳການ return value ຂອງ parsed data.&lt;/p&gt;

&lt;p&gt;ແລ້ວແນວໃດຕໍ່? ເຮົາຈະບໍ່ສົນໃຈ promise object ທັງໝົດທີ່ວ່າມາ, ເຮົາສົນໃຈພຽງ value ຂອງ data ທີ່ຖືກໂຍນອອກມາເທົ່ານັ້ນ, ມັນຈະມີ built-in methods 3 ໂຕທີ່ເຮັດໃຫ້ເຮົາສາມາດດຶງ promise value ອອກມາໃຊ້ໄດ້.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.then()&lt;/code&gt;: ຖືກເອີ້ນເມື່ອ promise ຖືກ resolved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.catch()&lt;/code&gt;: ຖືກເອີ້ນເມື່ອ promise ຖືກ rejected.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.finally()&lt;/code&gt;: ຈະຖືກເອີ້ນທຸກຄັ້ງບໍ່ວ່າ promise ຈະ resolved ຫຼື rejected ກໍ່ຕາມ.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kK43Ayqo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--19tIvFJQ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mu1aqqnyfjsfon5hwrtw.png" alt="built in method" width="800" height="269"&gt;
*&lt;code&gt;{&lt;/code&gt; ໃນຮູບດ້ານເທິງໜ້າຈະໃສ່ມາຜິດ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;.then&lt;/code&gt; method ຈະຮັບ value ທີ່ຖືກ pass ມາໃນ resolve method.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RfZg21zr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--DZld0c-0--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/11vxhn9cun7stpjbdi80.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RfZg21zr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--DZld0c-0--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/11vxhn9cun7stpjbdi80.gif" alt="then method" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;code&gt;.catch&lt;/code&gt; method ຈະຮັບ value ທີ່ຖືກ pass ມາໃນ rejected method.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pY5LAqR9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--e9SZHcPk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v5y24jz4u89flazvdyn4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pY5LAqR9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--e9SZHcPk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/v5y24jz4u89flazvdyn4.gif" alt="catch method" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ໃນທີ່ສຸດເຮົາກໍ່ໄດ້ value ທີ່ຖືກ resolve ໂດຍ promise ໂດຍທີ່ບໍ່ໄດ້ຢູ່ໃນຮູບແບບຂອງ promise object, ເຊິ່ງເຮົາສາມາດນຳ value ດັ່ງກ່າວໄປເຮັດຫຍັງກໍ່ໄດ້.&lt;/p&gt;




&lt;p&gt;ເມື່ອເຮົາຮູ້ແລ້ວວ່າ promise ຈະທຳການ resolve ຫຼື reject ທຸກໆຄັ້ງ, ດັ່ງນັ້ນເຮົາກໍ່ສາມາດຂຽນ &lt;code&gt;Promise.resolve&lt;/code&gt; ຫຼື &lt;code&gt;Promise.reject&lt;/code&gt; ດ້ວຍການ pass value ທີ່ເຮົາຕ້ອງການ resolve ຫຼື reject ເຂົ້າໄປໃຫ້ promise ໄດ້ດັ່ງນີ້.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ueAyfvu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--61Gva3Ze--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/90hxwjfadzslvdbkr4l8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ueAyfvu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--61Gva3Ze--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/90hxwjfadzslvdbkr4l8.png" alt="Promise.resolve and Promise.reject" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ໃນຕົວຢ່າງຕໍ່ໄປກໍ່ຈະໄດ້ໃຊ້ syntax ແບບນີ້ເປັນຫຼັກ.&lt;/p&gt;




&lt;p&gt;ຢູ່ໃນຕົວຢ່າງຂອງ &lt;code&gt;getImage&lt;/code&gt; ເຮົາມີ nested callback function ຫຼາຍອັນ, ເຊິ່ງເຮົາກໍ່ສາມາດໃຊ້ &lt;code&gt;.then&lt;/code&gt; ໃນການຈັດການກັບ code ສ່ວນນີ້🤩.&lt;br&gt;
result ຂອງ &lt;code&gt;.then&lt;/code&gt; ເອງກໍ່ແມ່ນ promise value ເຊັ່ນກັນ-ໝາຍຄວາມວ່າເຮົາສາມາດໃຊ້ &lt;code&gt;.then&lt;/code&gt; ເປັນ chain ຕໍ່ກັນຫຼາຍໆ &lt;code&gt;.then&lt;/code&gt; ເທົ່າທີ່ເຮົາຕ້ອງການໄດ້. ເຊິ່ງ result ຂອງ &lt;code&gt;.then&lt;/code&gt; callback ກ່ອນໜ້າຈະຖືກ pass ເປັນໜຶ່ງ argument &lt;br&gt;
ໃນ &lt;code&gt;.then&lt;/code&gt; callback ຕໍ່ໄປ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rr34OJSf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--X8h-NDc2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i6busbetmoya9vny2eku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rr34OJSf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--X8h-NDc2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i6busbetmoya9vny2eku.png" alt="then chain" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ໃນກໍລະນີຂອງຕົວຢ່າງ &lt;code&gt;getImage&lt;/code&gt; ເຮົາສາມາດຂຽນ &lt;code&gt;.then&lt;/code&gt; callback chain ໄດ້ເຊັ່ນກັນໂດຍເຮົາຈະທຳການ pass ໄຟລ໌ຮູບເຂົ້າໄປໃນ function ຕໍ່ໄປແທນທີ່ຈະໃຊ້ nested callback ຫຼາຍໆຊັ້ນເຊິ່ງມັນຈະເຮັດໃຫ້ code ຂອງເຮົາອ່ານງ່າຍຂຶ້ນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Buo0y3jA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--e1nVrqe1--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u9l3lxwxlxgv2edv79xh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Buo0y3jA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--e1nVrqe1--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u9l3lxwxlxgv2edv79xh.png" alt="then chain in getImage example" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Microtasks and (Macro)tasks
&lt;/h3&gt;

&lt;p&gt;ມາຮອດບ່ອນນີ້ເຮົາກໍ່ໄດ້ຮູ້ວິທີສ້າງ promise ແລະ ວິທີຈັດການກັບ values ທີ່ໄດ້ຈາກ promise ກັນໄປແລ້ວ, ເຮົາລອງເພີ່ມ script ອີກໜ້ອຍໜຶ່ງແລ້ວທຳການ run ລອງເບິ່ງອີກຄັ້ງລອງເບິ່ງ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dhea4jcR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uNG7sXon--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ey4ubnv5yjgi6hbh97xq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dhea4jcR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uNG7sXon--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ey4ubnv5yjgi6hbh97xq.gif" alt="microtask queue" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ເຫັນຫຍັງບໍ່?🤯 ນັ້ນມັນແບ້ຫຍັງຫັ້ນ?&lt;br&gt;
ທຳອິດເຮົາຈະ log ຄຳວ່າ &lt;code&gt;Start!&lt;/code&gt; ອອກມາ, ເຊິ່ງບ່ອນນີ້ກໍ່ເປັນຜົນມາຈາກ code ໃນແຖວທຳອິດ. ຕໍ່ມາເຮົາຈະເຫັນວ່າມັນ log ຄຳວ່າ &lt;code&gt;End!&lt;/code&gt; ແທນທີ່ຈະເປັນ value ຂອງ &lt;code&gt;Promise.resolve&lt;/code&gt; ແຕ່ສ່ວນນີ້ພັດຖືກ log ອອກມາຫຼັງຈາກ &lt;code&gt;End!&lt;/code&gt;. ເຮົາມາເບິ່ງນຳກັນຕໍ່ວ່າມັນເກີດຫຍັງຂຶ້ນໃນສ່ວນນີ້.&lt;br&gt;
ມາຮອດບ່ອນນີ້ເຮົາກໍ່ເຫັນແລ້ວວ່າ &lt;code&gt;promises&lt;/code&gt; ມັນເຮັດຫຍັງໄດ້ແນ່, ເຖິງ JavaScript ມັນຈະເປັນ single-thread ແຕ່ເຮົາກໍ່ສາມາດເພິ່ມຄວາມສາມາດແບບ asynchronous ໂດຍໃຊ້ &lt;code&gt;Promise&lt;/code&gt; ໄດ້ເຊັ່ນກັນ.&lt;br&gt;
ແຕ່ຮູ້ສຶກວ່າເຮົາໄດ້ເວົ້າເຖິງເລື່ອງນີ້ໄປແລ້ວໃນບົດຄວາມ EP1: Event loop?🤔, ແຕ່ເຮົາຍັງສາມາດໃຊ້ວິທີການແບບເດີມໆທີ່ເຮົາເຄີຍເຮັດຜ່ານມາເຊັ່ນ: setTimeout ໃນການສ້າງ asynchronous behavior ບາງປະເພດໄດ້ຫຼືບໍ່?🧐🤨🤯&lt;br&gt;
ແມ່ນແລ້ວ, ແຕ່ໃນ Event loop ມີຄິວ(Queues)ຢູ່ 2 ປະເພດຄື: (macro)task queue (ບາງຄັ້ງກໍ່ເອີ້ນວ່າ task queue) ແລະ microtask queue. ເຊິ່ງ (macro)task queue ກໍ່ເປັນ queue ສຳລັບ (macro)tasks ແລະ microtask queue ກໍ່ເປັນ queue ສຳລັບ microtask.&lt;br&gt;
ແລ້ວ (macro)task ແລະ microtask ແມ່ນຫຍັງ?, ມາທຳຄວາມເຂົ້າໃຈໄປພ້ອມໆກັນເລີຍ.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SW_VF6kv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6yjvljj7jdt17un9lpxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SW_VF6kv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6yjvljj7jdt17un9lpxu.png" alt="(macro)task and microtask" width="800" height="125"&gt;&lt;/a&gt;&lt;br&gt;
ຈາກຕາຕະລາງຈະເຫັນວ່າ &lt;code&gt;Promise&lt;/code&gt; ຈະຢູ່ໃນ microtask list, ເມື່ອ &lt;code&gt;Promise&lt;/code&gt; ທຳການ resolve ແລະ ໄດ້ເອີ້ນໃຊ້ &lt;code&gt;then()&lt;/code&gt;, &lt;code&gt;catch()&lt;/code&gt; ຫຼື &lt;code&gt;finally()&lt;/code&gt; method. callback ທີ່ຢູ່ໃນ method ຈະຖືກເພີ່ມເຂົ້າໃນ &lt;strong&gt;microtask queue&lt;/strong&gt; ໝາຍຄວາມວ່າບັນດາ callback ທີ່ຢູ່ໃນ &lt;code&gt;then()&lt;/code&gt;, &lt;code&gt;catch()&lt;/code&gt; ຫຼື &lt;code&gt;finally()&lt;/code&gt; method ຈະບໍ່ຖືກ execute ທັນທີ, ແຕ່ໂດຍພື້ນຖານແລ້ວມັນຈະທຳການເພີ່ມ &lt;code&gt;async&lt;/code&gt; ໃຫ້ JavaScript code ຂອງເຮົາໂດຍອັດຕະໂນມັດຢູ່ແລ້ວ.&lt;br&gt;
ແລ້ວ &lt;code&gt;then()&lt;/code&gt;, &lt;code&gt;catch()&lt;/code&gt; ຫຼື &lt;code&gt;finally()&lt;/code&gt; callback ຖືກ execute ຕອນໃດ? event loop ຈະເປັນຕົວທີ່ຈັດການກັບ priority ໃຫ້ແຕ່ລະ tasks ແຕກຕ່າງກັນດັ່ງນີ້:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function ທັງໝົດທີ່ຢູ່ໃນ &lt;strong&gt;call stack&lt;/strong&gt; ຈະຖືກ execute, ເມື່ອມັນໄດ້ທຳການ return value ອອກມາ ພວກມັນຈະຖືກໂຍນອອກ(pop)ຈາກ call stack.&lt;/li&gt;
&lt;li&gt;ເມື່ອ call stack ວ່າງ, microtasks ທັງໝົດທີ່ຢູ່ໃນ queue ຈະຖືກໂຍນມາທີ່ callstack ເທື່ອລະຕົວ ແລະ ທຳການ execute ຕໍ່ໄປ(ໂຕ Microtasks ເອງກໍ່ຍັງສາມາດ return microtasks ໃໝ່ອອກມາໄດ້ເຊັ່ນກັນ, ເຊິ່ງມັນຈະສ້າງ infinite microtask loop ໄດ້ຢ່າງມີປະສິດທິພາບ).&lt;/li&gt;
&lt;li&gt;ຖ້າຫາກທັງ call stack ແລະ microtask queue ວ່າງ, event loop ຈະທຳການກວດເບິ່ງ tasks ທີ່ຍັງຄ້າງຢູ່ໃນ (macro)task queue ວ່າຍັງມີຫຼືບໍ່?, ຖ້າມີມັນກໍ່ຈະຖືກໂຍນມາທີ່ callstack ເພື່ອທຳການ execute ແລະ ເມື່ອ return value ອອກໄປແລ້ວມັນຈະທຳການໂຍນ task ອອກຈາກ callstack.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;ເພື່ອໃຫ້ເຫັນພາບຫຼາຍຂຶ້ນ, ເຮົາມາເບິ່ງຕົວຢ່າງງ່າຍໆດ້ານລຸ່ມນຳກັນ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Task1: function ທີ່ຖືກເພີ່ມເຂົ້າໄປໃນ call stack ຈະຖືກ execute ທັນທີ, ຕົວຢ່າງ: ການເອີ້ນໃຊ້ function ທີ່ຢູ່ໃນ code ຂອງເຮົາມັນຈະຖືກເອີ້ນໃຊ້ທັນທີ.&lt;/li&gt;
&lt;li&gt;Task2, Task3, Task4: microtasks, ຕົວຢ່າງ: promise &lt;code&gt;then&lt;/code&gt; callback ຫຼື task ທີ່ຖືກເພີ່ມໂດຍ &lt;code&gt;queueMicrotask&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Task5, Task6: (macro)task, ຕົວຢ່າງ: setTimeout ຫຼື setImmediate callback.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--btJk22Cu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--05Fi8vBq--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/42eatw03fcha0e1qcrf0.gif" alt="task queue and microtask queue with event loop" width="800" height="450"&gt;
ທຳອິດ &lt;code&gt;Task1&lt;/code&gt; ຈະທຳການ return value ແລະ ຈະຖືກໂຍນອອກຈາກ call stack. ຈາກນັ້ນ engine ຈະກວດເບິ່ງ tasks queue ທີ່ຢູ່ໃນ microtask queue. ເມື່ອ tasks ທັງໝົດຖືກເພີ່ມເຂົ້າໄປໃນ call stack ແລະ ຖືກໂຍນອອກໃນຕອນສຸດທ້າຍ engine ຈະທຳການກວດເບິ່ງ task ທີ່ຍັງເຫຼືອໃນ (macro)task queue ຕໍ່ ແລະ ຈະທຳການເພີ່ມເຂົ້າໄປໃນ call stack ແລະ ໂຍນອອກຫຼັງຈາກທີ່ມັນໄດ້ທຳການ return value ອອກມາ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ດຽວເຮົາມາເບິ່ງຈາກ code ເລີຍດີກວ່າ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7VzJnyf0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--fnbqqf1d--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g61wwyi8wchk2hpzeq4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7VzJnyf0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--fnbqqf1d--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g61wwyi8wchk2hpzeq4u.png" alt="call stack example" width="800" height="579"&gt;&lt;/a&gt;&lt;br&gt;
ໃນ code ດ້ານເທິງເຮົາມີ macro task ແມ່ນ &lt;code&gt;setTimeout&lt;/code&gt; ແລະ microtask ແມ່ນ promise &lt;code&gt;then()&lt;/code&gt; callback, ເມື່ອ engine ເຮັດວຽກມາຮອດແຖວຂອງ &lt;code&gt;setTimeout&lt;/code&gt; function ຈະເກີດຫຍັງຂຶ້ນ? ເຮົາໄປເບິ່ງການເຮັດວຽກຂອງແຕ່ລະຂັ້ນຕອນນຳກັນເລີຍວ່າເຮົາຈະເຫັນຫຍັງໃນ log ແນ່.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ປລ: ໃນຕົວຢ່າງຕໍ່ໄປແມ່ນຈະສະແດງເຖິງບັນດາ methods ເຊັ່ນ: &lt;code&gt;console.log&lt;/code&gt;, &lt;code&gt;setTimeout&lt;/code&gt; ແລະ &lt;code&gt;Promise.resolve&lt;/code&gt; ທີ່ຖືກເພີ່ມເຂົ້າໄປໃນ call stack. ເຊິ່ງພວກມັນເປັນ internal methods ດັ່ງນັ້ນເຮົາອາດຈະບໍ່ເຫັນມັນປາກົດຢູ່ໃນ stack traces, ແຕ່ບໍ່ຕ້ອງຕົກໃຈໄປ ຖ້າຫາກໃຊ້ debugger ແລ້ວບໍ່ເຫັນ ເນື່ອງຈາກເຮົາຕ້ອງການຍົກຕົວຢ່າງໃຫ້ເຫັນຄອນເຊັບຂອງການເຮັດວຽກຂອງມັນໂດຍທີ່ບໍ່ໄດ້ຂຽນ code ທີ່ຊັບຊ້ອນຫຍັງ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ໃນແຖວທຳອິດ, engine ຈະພົບ &lt;code&gt;console.log()&lt;/code&gt; method, ມັນຈະຖືກເພີ່ມເຂົ້າໄປໃນ call stack ຫຼັງຈາກນັ້ນມັນຈະ log ຄ່າ &lt;code&gt;Start!&lt;/code&gt; ອອກມາຜ່ານ console ແລະ method ດັ່ງກ່າວຈະຖືກໂຍນອອກຈາກ call stack ແລ້ວ engine ກໍ່ຈະດຳເນີນການເຮັດວຽກຂອງມັນຕໍ່ໄປ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GyGxUZS0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s---Bt6DKsn--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6cbjuexvy6z9ltk0bi18.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GyGxUZS0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s---Bt6DKsn--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6cbjuexvy6z9ltk0bi18.gif" alt="engine encounter console.log" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຕໍ່ມາ engine ຈະພົບ &lt;code&gt;setTimeout&lt;/code&gt; method, ເຊິ່ງມັນກໍ່ຈະຖືກເພີ່ມເຂົ້າໄປໃນ call stack. ຕົວ &lt;code&gt;setTimeout&lt;/code&gt; method ແມ່ນເປັນ method ຂອງ browser ໂດຍທີ່ call back function ຂອງມັນ(&lt;code&gt;() =&amp;gt; console.log('Timeout')&lt;/code&gt;)ຈະຖືກເພີ່ມເຂົ້າໄປໃນ Web API ຈົນກວ່າ timer ເຮັດວຽກສຳເລັດ. ແຕ່ໃນທີ່ນີ້ເຮົາໄດ້ກຳນົດຄ່າໃຫ້ timer ມີຄ່າເປັນ &lt;code&gt;0&lt;/code&gt; ແຕ່ call back ກໍ່ຍັງຄົງຖືກເພີ່ມລົງໄປໃນ Web API ກ່ອນຢູ່ດີ. ຫຼັງຈາກນັ້ນມັນຈະຖືກເພີ່ມເຂົ້າໄປໃນ &lt;strong&gt;(macro)task queue&lt;/strong&gt;: &lt;code&gt;setTimeout&lt;/code&gt; ເປັນ macro task.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A9mz4GwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--6NSYq-nO--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yqoemb6f32lvovge8yrp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9mz4GwG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--6NSYq-nO--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yqoemb6f32lvovge8yrp.gif" alt="setTimeout is macro task" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
step ຕໍ່ໄປ engine ຈະພົບ &lt;code&gt;Promise.resolve()&lt;/code&gt; method. &lt;code&gt;Promise.resolve()&lt;/code&gt; method ຈະຖືກເພີ່ມເຂົ້າໄປໃນ call stack, ຫຼັງຈາກທີ່ມັນທຳການ resolve ດ້ວຍ value &lt;code&gt;Promise!&lt;/code&gt; ແລ້ວ, &lt;code&gt;then&lt;/code&gt; callback function ຈະຖືກເພີ່ມເຂົ້າໄປໃນ &lt;strong&gt;microtask queue&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kiVR89Qq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--us8FF30N--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6wxjxduh62fqt531e2rc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kiVR89Qq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--us8FF30N--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6wxjxduh62fqt531e2rc.gif" alt="Promise added to call stack" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ເມື່ອ engine ເຮັດວຽກມາຮອດແຖວສຸດທ້າຍມັນຈະພົບ &lt;code&gt;console.log()&lt;/code&gt; method. ມັນຈະຖືກເພີ່ມເຂົ້າໄປໃນ call stack ທັນທີ, ຫຼັງຈາກມັນໄດ້ທຳການ log ຄ່າ &lt;code&gt;End!&lt;/code&gt; ອອກມາທາງ console ແລ້ວ ມັນຈະຖືກໂຍນອອກຈາກ call stack ທັນທີ. ສ່ວນ engine ຈະເຮັດວຽກສ່ວນທີ່ເຫຼືອຕໍ່ໄປ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lu62chv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--oOS_-CiG--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a6jk0exl137yka3oq9k4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lu62chv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--oOS_-CiG--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a6jk0exl137yka3oq9k4.gif" alt="console.log added to call stack" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ມາຮອດບ່ອນນີ້ engine ຈະເຫັນວ່າ call stack ຂອງເຮົາວ່າງຢູ່. ເມື່ອ call stack ວ່າງມັນຈະໄປກວດເບິ່ງ task ທີ່ລໍຖ້າຢູ່ &lt;code&gt;microtask queue&lt;/code&gt; ໃນ code ຕົວຢ່າງຂອງເຮົາຈະເຫັນວ່າຍັງມີ promise &lt;code&gt;then&lt;/code&gt; callback ທີ່ຍັງລໍຖ້າຢູ່, ດັ່ງນັ້ນມັນຈຶ່ງຖືກໂຍນເຂົ້າໄປໃນ call stack ຫຼັງຈາກນັ້ນມັນຈະທຳການ resolve value ຂອງ promise ເຊິ່ງໃນຕົວຢ່າງແມ່ນມັນຈະ log ຄ່າ &lt;code&gt;Promise!&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cszEGCjH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--5iH5BNWm--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lczn4fca41is4vpicr6w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cszEGCjH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--5iH5BNWm--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lczn4fca41is4vpicr6w.gif" alt="resolve value of promise" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
call stack ເຫັນວ່າຄິວວ່າງພໍດີມັນເລີຍເຂົ້າໄປກວດຢູ່ &lt;strong&gt;microtask queue&lt;/strong&gt; ອີກຄັ້ງເພື່ອຊອກເບິ່ງວ່າຍັງມີ task ທີ່ຍັງຕໍ່ຄິວ(queue)ຫຼືບໍ່? ແຕ່ວ່າໃນກໍລະນີນີ້ microtask queue ກໍ່ວ່າງເຊັ່ນກັນ🤷🏻.&lt;br&gt;
ເມື່ອຫາຢູ່ microtassk queue ບໍ່ເຫັນມັນຈຶ່ງທຳການໄປຫາຢູ່ &lt;strong&gt;(macro)task queue&lt;/strong&gt; ຕໍ່, ເຊິ່ງໃນນີ້ຍັງມີ &lt;code&gt;setTimeout&lt;/code&gt; callback ທີ່ຍັງຖ້າແລ້ວຖ້າອີກ ແຕ່ຕອນນີ້ເຖິງເວລາທີ່ຕ້ອງໂຍນເຂົ້າໄປໃນ call stack ແລ້ວ. callback function ທຳການ return &lt;code&gt;console.log&lt;/code&gt; method ທີ່ທຳການ log ຄ່າ &lt;code&gt;"Timeout!"&lt;/code&gt; ອອກໄປ. ຫຼັງຈາກນັ້ນ &lt;code&gt;setTimeout&lt;/code&gt; callback ຈະຖືກໂຍນອອກຈາກ call stack.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nyWwV-l---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--hPFPTZp2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p54casaaz9oq0g8ztpi5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nyWwV-l---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--hPFPTZp2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p54casaaz9oq0g8ztpi5.gif" alt="setTimeout callback" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຈາກຕົວຢ່າງດ້ານເທິງກໍ່ນັບວ່າຈົບບໍລິບູນສຳລັບຕົວຢ່າງນີ້.&lt;/p&gt;




&lt;h3&gt;
  
  
  Async/Await
&lt;/h3&gt;

&lt;p&gt;ES7 ໄດ້ແນະນຳວິທີໃໝ່ໃນການເພີ່ມ async behavior ໃນ JavaScript ແລະ ເຮັດໃຫ້ມັນເຮັດວຽກຮ່ວມກັບ promises ແບບງ່າຍໆ. ເຊິ່ງໃນນັ້ນຈະໃຊ້ &lt;code&gt;async&lt;/code&gt; ແລະ &lt;code&gt;await&lt;/code&gt; keyword ໃນການສ້າງ &lt;code&gt;async&lt;/code&gt; functions ທີ່ສາມາດ return promise ອອກມາໄດ້, ສ່ວນວິທີການຈະເປັນແນວໃດນັ້ນ ໄປເບິ່ງນຳກັນເລີຍ.&lt;br&gt;
ກ່ອນໜ້ານີ້ເຮົາໄດ້ເຫັນແລ້ວວ່າເຮົາສາມາດສ້າງ Promise ໄດ້ໂດຍໃຊ້ &lt;code&gt;Promise&lt;/code&gt; object, ເຊິ່ງມັນກໍ່ຍັງມີອີກແບບອື່ນໆເຊັ່ນ: &lt;code&gt;new Promise(() =&amp;gt; {})&lt;/code&gt;, &lt;code&gt;Promise.resolve&lt;/code&gt;, ຫຼື &lt;code&gt;Promise.reject&lt;/code&gt;.&lt;br&gt;
ແທນທີ່ຈະໃຊ້ &lt;code&gt;Promise&lt;/code&gt; object ເຮົາສາມາດສ້າງ asynchronous functions ທີ່ return object ອອກມາໄດ້ເລີຍໂດຍທີ່ເຮົາບໍ່ຈຳເປັນຕ້ອງໄປຂຽນ &lt;code&gt;Promise&lt;/code&gt; object ດ້ວຍຕົວເອງ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T9kgV7v6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--5ED_HyNC--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/72lqrcvy9lc8ehbpitd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T9kgV7v6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--5ED_HyNC--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/72lqrcvy9lc8ehbpitd0.png" alt="asynchronous functions" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຖິງແມ່ນວ່າໃນຄວາມເປັນຈິງແລ້ວ &lt;code&gt;async&lt;/code&gt; functions ສາມາດ return promises ອອກມາໄດ້ນັ້ນກໍ່ນັບວ່າເປັນເລື່ອງດີ, ແຕ່ວ່າການທີ່ເຮົາຈະສາມາດສຳຜັດເຖິງຂຸມພະລັງທີ່ແທ້ຈິງຂອງ &lt;code&gt;async&lt;/code&gt; functions ໄດ້ນັ້ນກໍ່ຄືຕອນທີ່ເຮົາໃຊ້ &lt;code&gt;await&lt;/code&gt; keyword. ດ້ວຍ &lt;code&gt;await&lt;/code&gt; keyword ເຮົາສາມາດລະງັບການເຮັດວຽກ(suspended)ຂອງ &lt;code&gt;asynchronous&lt;/code&gt; function ໃນຂະນະທີ່ເຮົາລໍຖ້າ &lt;code&gt;await&lt;/code&gt; value ຖືກ return ຈາກການ resolve promise ໄດ້ນັ້ນເອງ🥳. ຖ້າເຮົາຕ້ອງການ value ຂອງ promise ຫຼັງຈາກທີ່ຖືກ resolve ແລ້ວນັ້ນເຮົາກໍ່ພຽງແຕ່ເຮັດຄືຕົວຢ່າງທີ່ຜ່ານມາຄືໃຊ້ &lt;code&gt;then()&lt;/code&gt; callback ແລະ ເຮົາຍັງສາມາດ assign variables ໃຫ້ກັບ &lt;code&gt;await&lt;/code&gt; promise value ໄດ້ນຳ.&lt;br&gt;
ມັນໝາຍຄວາມວ່າເຮົາສາມາດລະງັບການເຮັດວຽກ(suspended)ຂອງ async function ໄດ້ຫວາ? ຊິວ່າຈັ່ງຊັ້ນກໍ່ໄດ້, ແຕ່ວ່າມັນໝາຍຄວາມວ່າແນວໃດລ່ະ?.&lt;br&gt;
ເຮົາໄປເບິ່ງ code ຕົວຢ່າງພ້ອມໆກັນເລີຍ:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FYNa1Vqx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--aOWmZxnV--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e5duygomitj9o455107a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FYNa1Vqx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--aOWmZxnV--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/e5duygomitj9o455107a.gif" alt="async function" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ເກີດຫຍັງຂຶ້ນກັບ code ຂອງເຮົາແນ່?&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lLYqTRm4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--bfscMU3t--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d27d7xxiekczftjyic4b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lLYqTRm4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--bfscMU3t--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d27d7xxiekczftjyic4b.gif" alt="call stack with async function" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ທຳອິດ engine ມັນຈະພົບກັບ &lt;code&gt;console.log&lt;/code&gt;. ມັນຈະຖືກໂຍນເຂົ້າໄປໃນ call stack ຫຼັງຈາກນັ້ນມັນຈະທຳການ log ຄ່າ &lt;code&gt;Before function!&lt;/code&gt; ອອກມາ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Ys4WbJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--wN7yFTnt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9wqej2269vmntfcuxs9t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Ys4WbJj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--wN7yFTnt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9wqej2269vmntfcuxs9t.gif" alt="call stack with async function2" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຈາກນັ້ນເຮົາໄດ້ທຳການເອີ້ນໃຊ້ async function ທີ່ຊື່ວ່າ &lt;code&gt;myFunc()&lt;/code&gt;, ຫຼັງຈາກນັ້ນຕົວ &lt;code&gt;myFunc()&lt;/code&gt; function ກໍ່ຈະເຮັດວຽກ. ໃນແຖວທຳອິດຂອງ function body ເຮົາໄດ້ທຳການເອີ້ນໃຊ້ console.log ອີກຄັ້ງ, ເທື່ອນີ້ມັນຈະ log ຄ່າ &lt;code&gt;In function!&lt;/code&gt;, ເຊິ່ງ console.log ຈະຖືກໂຍນເຂົ້າໄປໃນ call stack, log ຄ່າອອກມາ ແລະ ຖືກໂຍນອອກຈາກ call stack ຕາມ step ເດີມໆ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G96lsRH1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--lX9JfreE--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lch6lutxnl88j0durpyh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G96lsRH1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--lX9JfreE--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/lch6lutxnl88j0durpyh.gif" alt="myFunc on call stack" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ໃນ function body ຍັງຄົງທຳການ execute ຕໍ່ໄປ, ເຊິ່ງເຮົາຈະເຫັນພະເອກຂອງເຮົາຄື &lt;code&gt;await&lt;/code&gt; keyword ຢູ່ໃນແຖວທີ 2 🥳🥳🥳.&lt;/p&gt;

&lt;p&gt;ສິ່ງທຳອິດທີ່ຈະເກີດຂຶ້ນກໍ່ຄື: value ຈະລໍຖ້າ execute, ເຊິ່ງໃນກໍລະນີນີ້ແມ່ນ &lt;code&gt;one&lt;/code&gt; function. ມັນຈະຖືກໂຍນເຂົ້າໄປໃນ call stack ແລະ ມັນຈະທຳການ return value ຂອງ resolve promise ອອກມາ. ເມື່ອ promise ຖືກ resolve ແລ້ວ ແລະ &lt;code&gt;one&lt;/code&gt; ໄດ້ return value ອອກມາ, ຈາກນັ້ນ engine ກໍ່ຈະພົບ &lt;code&gt;await&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;ເມື່ອມັນພົບ &lt;code&gt;await&lt;/code&gt; keyword ແລ້ວ, &lt;code&gt;async&lt;/code&gt; function ຈະຖືກລະງັບການເຮັດວຽກ(suspended). ການ execute ພາຍໃນ function body ຈະທຳການຢຸດຊົ່ວຄາວ(paused) ແລະ ສ່ວນທີ່ເຫຼືອໃນ &lt;code&gt;async&lt;/code&gt; function ຈະໄປ run ຢູ່ microtask ແທນ task ທຳມະດາແທນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dN73NECb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--UC78HoCO--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b6l3psgewvtrtmrr60tg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dN73NECb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--UC78HoCO--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b6l3psgewvtrtmrr60tg.gif" alt="finally call console.log" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຕອນນີ້ async function ທີ່ຊື່ວ່າ &lt;code&gt;myFunc&lt;/code&gt; ຈະຖືກລະງັບການເຮັດວຽກ(suspended)ໃນກໍລະນີທີ່ທັນພົບ &lt;code&gt;await&lt;/code&gt; keyword, engine ຈະໂດດອອກຈາກ &lt;code&gt;async&lt;/code&gt; function ແລະ ທຳການ execute code ຕໍ່ໄປໃນບໍລິບົດຂອງການ execution ທີ່ &lt;code&gt;async&lt;/code&gt; function ຖືກເອີ້ນໃຊ້. ເຊິ່ງໃນກໍລະນີນີ້ແມ່ນ &lt;strong&gt;global execution context&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMxMhN4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--V8u36kEG--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hlhrtuspjyrstifubdhs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMxMhN4d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--V8u36kEG--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hlhrtuspjyrstifubdhs.gif" alt="after await" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ສຸດທ້າຍກໍ່ບໍ່ເຫຼືອ task ໃດທີ່ຢູ່ໃນ global execution context. event loop ຈະທຳການກວດເບິ່ງວ່າພົບ microtasks ທີ່ລໍຖ້າ queue ຢູ່ຫຼືບໍ່? ແລະ ມັນກໍ່ຍັງມີ async &lt;code&gt;myFunc&lt;/code&gt; function ທີ່ຢູ່ໃນ queue ຫຼັງຈາກທີ່ທຳການ resolve value ຂອງ &lt;code&gt;one&lt;/code&gt;. &lt;code&gt;myFunc&lt;/code&gt; ຈະຖືກເພີ່ມເຂົ້າໄປໃນ call stack ອີກຄັ້ງ ແລະ ທຳການ run ຕໍ່ຈາກທີ່ຄ້າງໄວ້ກ່ອນໜ້ານີ້.&lt;/p&gt;

&lt;p&gt;ໃນທີ່ສຸດ variable &lt;code&gt;res&lt;/code&gt; ກໍ່ໄດ້ value ອອກມາ, ເຊິ່ງມັນກໍ່ເປັນ value ທີ່ຖືກ resolve ຈາກ promise ນັ້ນກໍ່ຄື &lt;code&gt;one&lt;/code&gt; ນັ້ນເອງ. ເຮົາໄດ້ທຳການເອີ້ນໃຊ້ &lt;code&gt;console.log&lt;/code&gt; ດ້ວຍ value ຂອງ res ໃນກໍລະນີນີ້ແມ່ນ &lt;code&gt;One!&lt;/code&gt;, ເຊິ່ງ &lt;code&gt;One!&lt;/code&gt; ຈະຖືກ log ອອກມາຜ່ານ console ແລະ ມັນຈະຖືກໂຍນອອກຈາກ call stack.&lt;/p&gt;

&lt;p&gt;ມາຮອດຕອນນີ້ກໍ່ເປັນອັນຈົບຊີຣີ່ຂອງ JavaScript ພື້ນຖານ(ແບບສຸດໆ), ຈາກຫຼາຍໆຕົວຢ່າງຜ່ານມາເຮົາກໍ່ຈະເຫັນພາບແລ້ວວ່າພາສາ JavaScript ເອງມັນກໍ່ມີຈຸດທີໜ້າສົນໃນໃນຫຼາຍໆເລື່ອງ ແລະ ຫຼາຍໆ feature ຢູ່ບໍ່ໜ້ອຍ, ຖ້າເຮົາເຂົ້າໃຈຂະບວນການເຮັດວໜກຂອງມັນເຮົາກໍ່ຈະສາມາດຂຽນ code ໄດ້ຢ່າງມີປະສິດທິພາບຫຼາຍຂຶ້ນ ແຕ່ທັງນີ້ກໍ່ຂຶ້ນກັບຄວາມຮູ້ດ້ານອື່ນໆນຳ.&lt;/p&gt;




&lt;p&gt;ອ້າງອີງ: &lt;a href="https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke"&gt;⭐️🎀 JavaScript Visualized: Promises &amp;amp; Async/Await&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JavaScript EP6: Generators and Iterators🔌🩻</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Mon, 24 Apr 2023 10:17:09 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep6-generators-and-iterators-354l</link>
      <guid>https://dev.to/phatsss/javascript-ep6-generators-and-iterators-354l</guid>
      <description>&lt;p&gt;ນັບຕັ້ງແຕ່ ES6 ເປັນຕົ້ນມາ, JavaScript ມີສິ່ງໜຶ່ງທີ່ໂຄດຄັກເລີຍນັ້ນກໍ່ຄື &lt;strong&gt;generator functions&lt;/strong&gt; ເຊິ່ງຫຼາຍໆຄົນທີ່ຂຽນ JavaScript ກໍ່ອາດຈະມີບາງຄົນທີ່ໃຊ້ ແລະ ສ່ວນໃຫຍ່ກໍ່ອາດຈະບໍ່ໄດ້ໃຊ້ເລີຍ, ແຕ່ຂໍບອກໄວ້ກ່ອນວ່າມັນ cool ອີ່ຫຼີ ຢາກໃຫ້ທຸກຄົນໄດ້ລອງ🛸.&lt;/p&gt;

&lt;p&gt;ວ່າແຕ່ generator functions ມັນແມ່ນແບ້ຫຍັງອີກແລ້ວວວວ?🤣, ທຳອິດເຮົາມາເບິ່ງ function ແບບທຳມະດາ ແລະ ແບບເດີມໆກັນກ່ອນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Fn2EadUt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--SPQNaFkb--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2ta7m1vxju6j1dzg7t7c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Fn2EadUt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--SPQNaFkb--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2ta7m1vxju6j1dzg7t7c.png" alt="normal function" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ຂ້ອຍຮູ້ວ່າພວກເຈົ້າຄິດຫຍັງຢູ່, ແຕ່ແມ່ນແລ້ວ ມັນກະແຄ່ function ທຳມະດາໆອັນໜຶ່ງ ແລະ ທາງໃນ function ມີການ log ຄ່າທີ່ເປັນ string ອອກມາ 4 ຕົວ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CeLhIE6N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--NYzqeCCE--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/unsiscmakhlgxl4dcji7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CeLhIE6N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--NYzqeCCE--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/unsiscmakhlgxl4dcji7.gif" alt="run normal function" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ບາງຄົນກໍ່ອາດຈະຄິດວ່າເປັນຫຍັງຕ້ອງມາ run code ໂງ່ໆໃຫ້ມັນເສຍເວລາຊີວິດເບິ່ງວ່ະ? ແຕ່ກະນັ້ນລ່ະ ເຮົາກໍ່ເຫັນວ່າ function ມັນກໍ່ເຮັດວຽກຕາມປົກກະຕິຂອງມັນຕັ້ງແຕ່ເລີ່ມຕົ້ນຈົນຈົບ(ຍົກເວັ້ນໃນກໍລະນີທີ່ມີຂໍ້ຜິດພາດອີ່ຫຍັງບາງຢ່າງ)ໂດຍໃຊ້ &lt;strong&gt;run-to-completion&lt;/strong&gt; ໂມເດວ, ປະເດັນຄືເຮົາບໍ່ສາມາດເຮັດໃຫ້ function ນີ້ຢຸດການເຮັດວຽກກາງຄັນໄດ້🤯.&lt;/p&gt;

&lt;p&gt;ມາຮອດຈຸດທີ່ຟິນທີ່ສຸດແລ້ວ: generator function ຈະບໍ່ໄດ້ follow ຕາມ run-to-completion model, ນີ້ໝາຍຄວາມວ່າເຮົາສາມາດຢຸດການເຮັດວຽກຂອງ generator function ໄດ້ໃນຂະນະທີ່ມັນເຮັດວຽກຢູ່ຫວາ? ໃຈເຢັນນນ!!! ເຮົາມາເບິ່ງນຳກັນກ່ອນວ່າ generator function ແມ່ນຫຍັງ? ແລະ ເຮົາຈະຈັດການກັບມັນໄດ້ດ້ວຍວິທີໃດແດ່.&lt;/p&gt;

&lt;p&gt;ເຮົາສາມາດຂຽນ generator function ໂດຍການຂຽນເຄື່ອງໝາຍດອກຈັນ ຫຼື ເຄື່ອງໝາຍດາວ ຫຼື ເຄື່ອງໝາຍແບ້ອີ່ຫຍັງຈັກຢ່າງທີ່ມີໜ້າຕາແບບນີ້(*) ຢູ່ທາງຫຼາຍຂອງ function keyword.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jOMelHS_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--hqnT9Dtn--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7j9pxfpvmecip71ldjwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jOMelHS_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--hqnT9Dtn--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7j9pxfpvmecip71ldjwg.png" alt="generator function" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ແຕ່ນັ້ນກໍ່ບໍ່ແມ່ນທັງໝົດຂອງສິ່ງທີ່ເຮົາຕ້ອງເຮັດ, ເນື່ອງຈາກ generator function ແລະ regular function ໂດຍທົ່ວໄປແຕກຕ່າງກັນຢ່າງສິ້ນເຊີງ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ການເອີ້ນໃຊ້ generator function ຈະທຳການ return &lt;strong&gt;generator object&lt;/strong&gt; ທີ່ເປັນ iterator.&lt;/li&gt;
&lt;li&gt;ເຮົາສາມາດໃຊ້ &lt;code&gt;yield&lt;/code&gt; keyword ໃນ generator function ເພື່ອເຮັດໃຫ້ function ນັ້ນຢຸດການເຮັດວຽກຊົ່ວຄາວ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ວ່າແຕ່ມັນໝາຍຄວາມວ່າຈັ່ງໃດລ່ະ?🤔.&lt;br&gt;
ເຮົາມາເລີ່ມກັນຕັ້ງແຕ່ທຳອິດເລີຍຄື: ການເອີ້ນໃຊ້ generator function ຈະມີການ return &lt;strong&gt;generator object&lt;/strong&gt; ອອກມາ. ແຕ່ເມື່ອເຮົາທຳການເອີ້ນໃຊ້ regular function, code ທີ່ຢູ່ໃນ function body ຈະຖືກ execute ແລະ ທຳການ return value ອອກມາປົກກະຕິ. ແຕ່ເຖິງຢ່າງໃດກໍ່ຕາມ, ເມື່ອເຮົາໄດ້ເອີ້ນໃຊ້ generator function ມັນຈະ return &lt;strong&gt;generator object&lt;/strong&gt; ອອກມາ, ເຊິ່ງເມື່ອເຮົາທຳການ log value ທີ່ໄດ້ເບິ່ງຈະມີໜ້າຕາດັ່ງນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xZk-LkkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--aXTBozny--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lyuivuuepy1hzpok8rc5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xZk-LkkP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--aXTBozny--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lyuivuuepy1hzpok8rc5.gif" alt="generator object" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຊື່ອວ່າຫຼາຍໆຄົນທີ່ອ່ານມາຮອດນີ້ຄົງຈະຫຼອນສົມຄວນຢູ່, ໃນການນຳໃຊ້ຕົວຈິງມັນອາດຈະບໍ່ມີຄວາມຈຳເປັນທີ່ຈະຕ້ອງໃຊ້ properties ທັງໝົດທີ່ເຮົາເຫັນໃນ log. ດຽວເຮົາມາເບິ່ງນຳກັນຕໍ່ວ່າ generator object ມັນສາມາດນຳໃຊ້ແນວໃດໄດ້ແນ່🥶.&lt;/p&gt;

&lt;p&gt;ທຳອິດເຮົາຈະຍ້ອນກັບໄປອີກໜ້ອຍໜຶ່ງເພື່ອທີ່ຈະຕອບຄຳຖາມທີ່ວ່າ: generator function ແຕກຕ່າງກັບ regular function ແນວໃດ?, ເຊິ່ງຄຳຕອບໃນທີ່ນີ້ກໍ່ຄົງຈະແມ່ນ: ໃນ generator function ເຮົາສາມາດໃຊ້ &lt;code&gt;yeild&lt;/code&gt; keyword ເພື່ອຢຸດການ execution ໄດ້.&lt;/p&gt;

&lt;p&gt;ຕົວຢ່າງ: ເຮົາສາມາດຂຽນ generator function ແບບນີ້ໄດ້.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K8IHDikA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--DMCbuRT2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1qo0upq0meh6gj2gs08o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K8IHDikA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--DMCbuRT2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1qo0upq0meh6gj2gs08o.png" alt="genFunc" width="800" height="593"&gt;&lt;/a&gt;&lt;br&gt;
ໃນ function ດ້ານເທິງ &lt;code&gt;yield&lt;/code&gt; keyword ເຮັດວຽກແນວໃດ?, ການ execution ຂອງ generator ຈະຢຸດ(&lt;code&gt;pause&lt;/code&gt;)ກໍ່ຕໍ່ເມື່ອມັນພົບ &lt;code&gt;yield&lt;/code&gt; keyword ແລະ ຈຸດພີກຂອງການໃຊ້ generator ຄືຕອນທີ່ເຮົາເອີ້ນໃຊ້ function ຄັ້ງຕໍ່ໄປຄື ມັນຈະຈື່ວ່າຄັ້ງຫຼ້າສຸດທີ່ມັນຖືກຢຸດມັນຖືກຢຸດຢູ່ບ່ອນໃດ ແລະ ມັນສາມາດດຳເນີນການຕໍ່ຈາກຈຸດເດີມໄປໄດ້ເລີຍ😱. ມາເບິ່ງນຳກັນວ່າມັນເກີດຫຍັງຂຶ້ນຢູ່ບ່ອນນີ້ແນ່?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ຄັ້ງທຳອິດທີ່ເຮົາ run, ມັນຈະ "pauses" ໃນແຖວທຳອິດ ແລະ yields ຄ່າ '✨' ທີ່ເປັນ string.&lt;/li&gt;
&lt;li&gt;ເມື່ອເຮົາ run ຄັ້ງທີ 2, ມັນຈະເລີ່ມຈາກແຖວທີ່ມັນຢຸດເທື່ອກ່ອນຄື &lt;code&gt;yield&lt;/code&gt; keyword ອັນທຳອິດ. ມັນຈະ run ໄປເລື້ອຍໆຈົນຮອດ &lt;code&gt;yield&lt;/code&gt; keyword ທີ 2 ແລະ yields ຄ່າ '💕' ທີ່ເປັນ string.&lt;/li&gt;
&lt;li&gt;ເມື່ອເຮົາ run ຄັ້ງທີ 3,​ ມັນຈະເລີ່ມຈາກແຖວທີ່ມັນຢຸດໄວ້ຈາກເທື່ອກ່ອນ ຫຼື ຈາກ &lt;code&gt;yield&lt;/code&gt; keyword ທີ 2. ເຊິ່ງມັນກໍ່ຈະເຮັດຄືເກົ່າກໍ່ຄືມັນຈະ run ໄປເລື້ອຍໆຈົນຮອດ &lt;code&gt;return&lt;/code&gt; keyword(ເນື່ອງຈາກບໍ່ມີ &lt;code&gt;yield&lt;/code&gt; keyword ອື່ນແລ້ວ) ແລະ ມັນຈະທຳການ return ຄ່າ &lt;code&gt;Done!&lt;/code&gt; ອອກໄປ.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ວ່າແຕ່ເຮົາຈະເອີ້ນໃຊ້ generator function ໄດ້ແນວໃດທັງໆທີ່ເຮົາກໍ່ເຫັນແລ້ວວ່າການທີ່ເຮົາເອີ້ນໃຊ້ generator function ມັນຈະ return generator object ອອກມາ?🤔 ບ່ອນນີ້ແຫຼະທີ່ເຮົາຈະໄດ້ generator object ອອກມາຫຼິ້ນ(ບອກໄດ້ເລີຍວ່າບັນເທີງກັນທົ່ວໜ້າ🤣).&lt;/p&gt;

&lt;p&gt;ໃນ generator object ຈະມີ &lt;code&gt;next&lt;/code&gt; method ມາໃຫ້ນຳ(ຢູ່ໃນ prototype chain). ເຊິ່ງ method ນີ້ເຮົາຈະໃຊ້ໃນການ iterate generator object, ແຕ່ໃນການທີ່ຈະຈື່ state ຂອງຈຸດທີ່ມັນຢຸດກ່ອນໜ້ານີ້ຫຼັງຈາກທີ່ມັນ yield value, ເຮົາຕ້ອງ assign generator object ໃນຮູບແບບຂອງ variable ໃນຕົວຢ່າງເຮົາໃຊ້ຊື່ວ່າ &lt;code&gt;genObj&lt;/code&gt; ຫຍໍ້ມາຈາກ &lt;code&gt;generatorObject&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RVXhtg2b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--23CZeKcI--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/y54clkzwbc9oemzgybh5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RVXhtg2b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--23CZeKcI--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/y54clkzwbc9oemzgybh5.gif" alt="generatorObject" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຮົາມາເບິ່ງກັນຕໍ່ອີກວ່າຈະເກີດຫຍັງຂຶ້ນຖ້າເຮົາເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ທີ່ຢູ່ໃນ &lt;code&gt;genObj&lt;/code&gt; generator object.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LeiXgIfD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--n1Qw3ur9--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ryzc9gpzw4x5f0eqhzad.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LeiXgIfD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--n1Qw3ur9--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ryzc9gpzw4x5f0eqhzad.gif" alt="genObj generator object" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;generator ຈະທຳການ run ຈົນກວ່າຈະພົບກັບ &lt;code&gt;yield&lt;/code&gt; keyword ທຳອິດ, ເຊິ່ງໃນຕົວຢ່າງມັນຈະຢູ່ແຖວທຳອິດ ມັນໄດ້ທຳການ yield object ທີ່ມີ &lt;code&gt;value&lt;/code&gt; property  ແລະ &lt;code&gt;done&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ value: ... , done: ... }&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;value&lt;/code&gt; property ຈະເປັນ value ທີ່ເຮົາໄດ້ທຳການ yield ໄວ້.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;done&lt;/code&gt; property ເປັນຄ່າ boolean, ທີ່ຈະເປັນຄ່າ true ກໍ່ຕໍ່ເມື່ອ generator function ໄດ້ທຳການ return value ອອກໄປແລ້ວ(ບໍ່ແມ່ນ yield)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ເຮົາໄດ້ທຳການຢຸດການ iterate ໃນ generator ທີ່ເບິ່ງຄືກັບວ່າ function ມັນຖືກ &lt;code&gt;paused&lt;/code&gt;, ບອກເລີຍວ່າສຸດຈັກປະລັກຂິກເລີຍ. ດຽວເຮົາມາລອງເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ອີກຮອບລອງເບິ່ງ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3tixTOQ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--9l_dv85d--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/e7hz87c6xtd31qjx19va.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3tixTOQ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--9l_dv85d--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/e7hz87c6xtd31qjx19va.gif" alt="call next method" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ທຳອິດເຮົາໄດ້ທຳການ log ຄ່າທີ່ເປັນ string ອອກມາເບິ່ງຈະໄດ້ &lt;code&gt;First log!&lt;/code&gt; ຢູ່ໃນ console.log(), ແຕ່ເນື່ອງຈາກມັນບໍ່ແມ່ນ &lt;code&gt;yield&lt;/code&gt; ຫຼື &lt;code&gt;return&lt;/code&gt; keyword ມັນຈຶ່ງເຮັດວຽກຕໍ່ຈົນກວ່າຈະພົບ &lt;code&gt;yield&lt;/code&gt; keyword ທີ່ໄດ້ຄ່າ &lt;code&gt;'💕'&lt;/code&gt;. object ທີ່ໄດ້ຈາກການ &lt;code&gt;yield&lt;/code&gt; ໂດຍ value property ຈະໄດ້ &lt;code&gt;'💕'&lt;/code&gt; ແລະ done property, ເຊິ່ງ done property ຈະຍັງເປັນຄ່າ &lt;code&gt;false&lt;/code&gt; ເນື່ອງຈາກ generator ຍັງບໍ່ມີການ return ເທື່ອ.&lt;/p&gt;

&lt;p&gt;ເຮົາມາລອງໃຊ້ &lt;code&gt;next&lt;/code&gt; method ອີກຮອບ, ໜ້າຈະເປັນຮອບສຸດທ້າຍແລ້ວມັ້ງ🤣&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xii1WgIG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--P1hGzgIq--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/33epxsx8znmhm0qojsuu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xii1WgIG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--P1hGzgIq--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/33epxsx8znmhm0qojsuu.gif" alt="last next method" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຮົາໄດ້ທຳການ log ຄ່າທີ່ເປັນ string ຈະໄດ້ &lt;code&gt;Second log!&lt;/code&gt; ຢູ່ໃນ console.log() ຄືເກົ່າ, ຈາກນັ້ນມັນຈະພົບ &lt;code&gt;return&lt;/code&gt; keyword ພ້ອມດ້ວຍຄ່າ &lt;code&gt;'Done!'&lt;/code&gt;. object ທີ່ຖືກ return ອອກມາຈະໄດ້ value property ແມ່ນ &lt;code&gt;'Done!'&lt;/code&gt;, ມາຮອດຕອນນີ້ເຮົາໄດ້ທຳການ return ຄ່າອອກໄປແລ້ວ ດັ່ງນັ້ນ value ຂອງ done property ຈະມີຄ່າເປັນ &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;done property ຖືວ່າເປັນອີກສ່ວນທີ່ສຳຄັນທີ່ສຸດເລີຍກໍ່ວ່າໄດ້, ເຊິ່ງເຮົາສາມາດ iterate generator object ໄດ້ພຽງຄັ້ງດຽວເທົ່ານັ້ນ. ແລ້ວຖ້າສົມມຸດເຮົາເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ອີກຮອບມັນຈະເກີດຫຍັງຂຶ້ນ?&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kOUKV1Cj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--Xe9VmNyb--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wooo83by4eh12akmg5wb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kOUKV1Cj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--Xe9VmNyb--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wooo83by4eh12akmg5wb.gif" alt="return from generator function" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຄຳຕອບກໍ່ງ່າຍໆເລີຍຄືມັນຈະທຳການ return ຄ່າ &lt;code&gt;undefined&lt;/code&gt; ອອກມາທຸກຄັ້ງ, ແຕ່ຖ້າຕ້ອງການຢາກຈະ iterate ອີກກໍ່ພຽງສ້າງ generator object ໃໝ່.&lt;/p&gt;




&lt;p&gt;ດັ່ງທີ່ເຮົາໄດ້ເຫັນດ້ານເທິງແລ້ວວ່າ generator function ຈະທຳການ return iterator(generator object), ແຕ່ iterator ແມ່ນຫຍັງອີກແລ້ວບາດນິ? ເອົາຄຳຕອບໄວ້ກ່ອນແລ້ວຄ່ອຍໄປເບິ່ງຕົວຢ່າງນຳກັນດ້ານລຸ່ມ. iterator ໝາຍເຖິງ object ທີ່ຖືກ return ອອກມາ ແລະ ເຮົາສາມາດໃຊ້ &lt;code&gt;for of&lt;/code&gt; loops ແລະ spread operator ກັບ object ນັ້ນໆໄດ້.&lt;/p&gt;

&lt;p&gt;ເຮົາລອງ spread ຄ່າທີ່ຖືກ yield ເຊິ່ງຈະເປັນຂໍ້ມູນຮູບແບບຂອງ array ໂດຍນຳໃຊ້ &lt;code&gt;[... ]&lt;/code&gt; syntax.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---REhZE30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--rZrIexdt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xgk99j592vbx3qirw5or.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---REhZE30--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--rZrIexdt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xgk99j592vbx3qirw5or.gif" alt="spread operator" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ຫຼື ອາດຈະໃຊ້ &lt;code&gt;for of&lt;/code&gt; loop&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UNngAKUV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--RAEn2yjk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/98k242jz3bqorkjhukwl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UNngAKUV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--RAEn2yjk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/98k242jz3bqorkjhukwl.gif" alt="for of" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຫຼື ອາດຈະໃຊ້ວິທີອື່ນກໍ່ໄດ້ເຊັ່ນກັນ.&lt;/p&gt;

&lt;p&gt;ແຕ່ວ່າແມ່ນຫຍັງທີ່ເຮັດໃຫ້ iterator ເປັນ iterator?😳 ຄຳຕອບງ່າຍກໍ່ຍ້ອນວ່າເຮົາສາມາດໃຊ້ &lt;code&gt;for-of&lt;/code&gt; loops ແລະ &lt;code&gt;spread&lt;/code&gt; syntax ກັບ arrays, strings, maps ແລະ sets ໄດ້ນັ້ນເອງ, ສ່ວນອີກເຫດຜົນກໍ່ຍ້ອນມັນມີການ implement ສິ່ງທີ່ເອີ້ນວ່າ &lt;strong&gt;iterator protocol&lt;/strong&gt;: &lt;code&gt;[Symbol.iterator]&lt;/code&gt;. ຖ້າຍັງບໍ່ເຂົ້າໃຈ ເຮົາມາເບິ່ງຕົວຢ່າງນຳກັນດີກວ່າ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q03kaCiL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--llTXHrg7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hs2sf1oj537c56yaej1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q03kaCiL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--llTXHrg7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hs2sf1oj537c56yaej1h.png" alt="iterator protocol" width="800" height="675"&gt;&lt;/a&gt;&lt;br&gt;
ບັນດາ &lt;code&gt;array&lt;/code&gt;,&lt;code&gt;string&lt;/code&gt; ແລະ &lt;code&gt;generatorObject&lt;/code&gt; ລ້ວນແລ້ວແຕ່ເປັນ iterators. ເຮົາລອງມາເບິ່ງ value ຂອງມັນດີກວ່າ &lt;code&gt;[Symbol.iterator]&lt;/code&gt; property.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--80q8-3dh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--WWSsnUX7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/a7inxsrvrp8ykg3xw6zu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--80q8-3dh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--WWSsnUX7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/a7inxsrvrp8ykg3xw6zu.gif" alt="Symbol.iterator" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ແຕ່ value ຂອງ &lt;code&gt;[Symbol.iterator]&lt;/code&gt; ທີ່ເຫັນຢູ່ໃນນັ້ນບໍ່ສາມາດ iterate ໄດ້ບໍ່? ເພື່ອຕອບຄຳຖາມນີ້ເຮົາໄປເບິ່ງຕົວຢ່າງນຳກັນເລີຍ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qaxmhMEb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--1IBldFRj--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tpuzuy58g8m7grxvqw8x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qaxmhMEb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--1IBldFRj--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tpuzuy58g8m7grxvqw8x.gif" alt="value of iterator" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຄຳຕອບທຳອິດຄື: ແມ່ນແລ້ວ😄, ແຕ່ໃຈເຢັນກ່ອນໄອ້ສອງຢ່າຟ້າວເສຍໃຈໄປ ຄ່າຂອງມັນແຄ່ບໍ່ໄດ້ຢູ່ບ່ອນນັ້ນຊື່ໆ🤣. ດັ່ງນັ້ນຖ້າຢາກໄດ້ value ອອກມາເຮົາກໍ່ພຽງແຕ່ທຳການ add &lt;code&gt;[Symbol.iterator]&lt;/code&gt; property ເຂົ້າໄປແບບ manual ແລະ ເຮົາຈະສາມາດ iterate ໄດ້ນັ້ນເອງ.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[Symbol.iterator]&lt;/code&gt; ມີການ return iterator ອອກມາ, ເຊິ່ງມັນຈະພ່ວງ &lt;code&gt;next&lt;/code&gt; method ທີ່ຈະ return object ອອກມາຄ້າຍໆກັບຕົວຢ່າງທີ່ເຮົາເຫັນຜ່ານມາ: &lt;code&gt;{ value: '...', done: false/true }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;ເພື່ອຄວາມງ່າຍ, ເຮົາສາມາດ set value ຂອງ &lt;code&gt;[Symbol.iterator]&lt;/code&gt; ໃຫ້ເທົ່າກັບ generator function ເຊິ່ງມັນຈະ return iterator ອອກມາໂດຍ default ຢູ່ແລ້ວ, ລອງສ້າງ object ທີ່ເຮົາສາມາດ iterate ໄດ້ ແລະ ທຳການ yield value ຂອງ object ທັງໝົດ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aXrVZHkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--S-0xsWy9--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oysyy7v71o2q9q9mrcsx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aXrVZHkw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--S-0xsWy9--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oysyy7v71o2q9q9mrcsx.png" alt="Symbol.iterator equal generator function" width="800" height="348"&gt;&lt;/a&gt;&lt;br&gt;
ສັງເກດເບິ່ງວ່າຈະເກີດຫຍັງຂຶ້ນຖ້າຫາກເຮົາໃຊ້ spread syntax ຫຼື &lt;code&gt;for-of&lt;/code&gt; loop ກັບ object ທີ່ເຮົາໄດ້ມາ&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tSozvS01--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--y4uwsswR--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pw2qq1tkfbp8zccuecac.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tSozvS01--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--y4uwsswR--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pw2qq1tkfbp8zccuecac.gif" alt="using spread syntax with iterator" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຫຼືເຮົາອາດຈະຕ້ອງການພຽງແຕ່ object keys, ຖ້າແບບນີ້ກໍ່ງ່າຍໆເລີຍ ເຮົາພຽງທຳການ yield &lt;code&gt;Object.keys(this)&lt;/code&gt; ແທນ &lt;code&gt;this&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VpJW78F1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--JKxhr5ZJ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ankit4dn67unnwzfkv9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VpJW78F1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--JKxhr5ZJ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ankit4dn67unnwzfkv9y.png" alt="Object.keys(this)" width="800" height="348"&gt;&lt;/a&gt;&lt;br&gt;
ມາເບິ່ງຜົນລັບນຳກັນ&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CgSKW8Wy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--OOE8nOyw--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/75kf40lqcqrudzqgkeb7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CgSKW8Wy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--OOE8nOyw--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/75kf40lqcqrudzqgkeb7.gif" alt="res of Object.keys(this)" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Object.keys(this)&lt;/code&gt; ເປັນ array, ດັ່ງນັ້ນ value ທີ່ຖືກ yield ຈະໄດ້ເປັນ array ຈາກນັ້ນເຮົາຈະ spread array ທີ່ເຮົາໄດ້ມາໄປເປັນ array ອື່ນໆ ສິ່ງທີ່ຈະເກີດຂຶ້ນກໍ່ຄືເຮົາຈະໄດ້ nested array ມາແທນ. ເຮົາບໍ່ໄດ້ຕ້ອງການ array ແບບນີ້, ເຮົາພຽງຕ້ອງການ yield ແຕ່ລະ key ເທົ່ານັ້ນ.&lt;/p&gt;

&lt;p&gt;ເຮົາສາມາດ yield value ຈາກ iterator ຢູ່ໃນ generator ໄດ້ໂດຍໃຊ້ &lt;code&gt;yield*&lt;/code&gt; keyword, ສົມມຸດວ່າເຮົາມີ generator function ທີ່ yield ທຳອິດຈະ yield "🥑" ຕໍ່ມາເຮົາມີການ yield values ມາຈາກ iterator(ໃນຕົວຢ່າງນີ້ເຮົາຈະໃຊ້ເປັນ array) ເຊິ່ງໃນກໍລະນີນີ້ເຮົາໄດ້ໃຊ້ &lt;code&gt;yield*&lt;/code&gt; keyword, ຈາກນັ້ນເຮົາໄດ້ທຳການແທນຄ່າດ້ວຍ generator ອື່ນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vhI7qZR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--8ZUO_nmt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jtyn5s5o3vdhjkbwwyb0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vhI7qZR6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--8ZUO_nmt--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jtyn5s5o3vdhjkbwwyb0.gif" alt="yield*" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ແຕ່ລະ value ຂອງ generator ທີ່ໄດ້ແທນຄ່າຈະຖືກ yield ກ່ອນທີ່ມັນຈະທຳການ iterate &lt;code&gt;genObj&lt;/code&gt; iterator ຕໍ່ໄປ.&lt;/p&gt;

&lt;p&gt;ນີ້ຄືສິ່ງທີ່ເຮົາຕ້ອງເຮັດໃນກໍລະນີທີ່ເຮົາຕ້ອງການ object keys ທັງໝົດ&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_vGCJCYl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--pDQ9YJem--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/btr4ytbb04c44qfs96v2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_vGCJCYl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--pDQ9YJem--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/btr4ytbb04c44qfs96v2.gif" alt="object keys" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;ສຳລັບການນຳໃຊ້ generator function ອີກແບບໜຶ່ງກໍ່ຄື: ເຮົາສາມາດໃຊ້ເປັນ observer functions ໄດ້, ເນື່ອງຈາກ generator ສາມາດລໍຖ້າ incoming data ແລະ ເມື່ອມີ data ຖືກສົ່ງຜ່ານເຂົ້າມາເທົ່ານັ້ນມັນຈຶ່ງຈະທຳການ process. ເບິ່ງຕົວຢ່າງດ້ານລຸ່ມ🧐&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S6H6pDMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--tfcD--K5--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fts36exs5chxacikjeo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S6H6pDMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--tfcD--K5--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fts36exs5chxacikjeo3.png" alt="generator as a observer functions" width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
ສິ່ງໜຶ່ງທີ່ຕ່າງກັນຢ່າງຊັດເຈນເລີຍໃນທີ່ນີ້ແມ່ນເຮົາບໍ່ໄດ້ມີພຽງ &lt;code&gt;yield [value]&lt;/code&gt; ຄືກັບທີ່ເຮົາເຫັນໃນຕົວຢ່າງທີ່ຜ່ານມາ, ແຕ່ເຮົາໄດ້ assign ຄ່າໄວ້ໃນຕົວປ່ຽນທີ່ຊື່ວ່າ &lt;code&gt;second&lt;/code&gt; ແລະ ມີການ yield value ທີ່ເປັນ string ເຊິ່ງມີຄ່າ &lt;code&gt;First!&lt;/code&gt;, ເຊິ່ງ value ນີ້ເອງຈະຖືກ yield ໃນຄັ້ງທຳອິດທີ່ເຮົາເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;ມາເບິ່ງວ່າຈະເກີດຫຍັງຂຶ້ນເມື່ອເຮົາເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ຄັ້ງທຳອິດ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WRNs45aA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--q1ylTmRk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ob5a4yi79it9q2ben137.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WRNs45aA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--q1ylTmRk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ob5a4yi79it9q2ben137.gif" alt="yield value &amp;amp; assign to const keyword" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ເມື່ອມັນພໍ້ &lt;code&gt;yield&lt;/code&gt; ໃນແຖວທຳອິດ ແລະ ມັນໄດ້ທຳການ yield value &lt;code&gt;First!&lt;/code&gt;, ດັ່ງນັ້ນ value ຂອງຕົວປ່ຽນ &lt;code&gt;second&lt;/code&gt; ຈະມີຄ່າແນວໃດ?&lt;/p&gt;

&lt;p&gt;ແນ່ນອນວ່າມັນຈະເປັນ value ທີ່ເຮົາສົ່ງໄປໃນ &lt;code&gt;next&lt;/code&gt; method ທີ່ເຮົາເອີ້ນໃຊ້ໃນຄັ້ງຕໍ່ໄປ, ເຮົາມາລອງສົ່ງ value ທີ່ເປັນ string ດັ່ງນີ້ &lt;code&gt;'I like JavaScript'&lt;/code&gt; ເຂົ້າໄປໃນ &lt;code&gt;next&lt;/code&gt; method.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pq2xQ1A2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--g9vc9eyY--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/l1840pp2k9h9bgpt1geo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pq2xQ1A2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--g9vc9eyY--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/l1840pp2k9h9bgpt1geo.gif" alt="pass value to next method" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ສິ່ງທີ່ສຳຄັນທີ່ຕ້ອງສັງເກດໃນທີ່ນີ້ຄື: ເບິ່ງວ່າການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ຍັງບໍ່ໄດ້ມີການ track input ໃດໆເທື່ອ ເຮົາພຽງ start observer ໂດຍການເອີ້ນໃຊ້ໃນຄັ້ງທຳອິດ. generator ຈະລໍຖ້າ input ຈາກເຮົາກ່ອນທີ່ມັນຈະສືບຕໍ່ການເຮັດວຽກຂອງມັນຕໍ່ໄປ ແລະ ອາດຈະປະມວນຜົນຄ່າທີ່ເຮົາສົ່ງໄປໃນ &lt;code&gt;next&lt;/code&gt; method.&lt;/p&gt;




&lt;p&gt;ເປັນຫຍັງເຮົາຈຶ່ງຕ້ອງໃຊ້ generator function?&lt;/p&gt;

&lt;p&gt;ຂໍ້ດີຢ່າງໜຶ່ງຂອງການໃຊ້ generator ຄືຄວາມຈິງທີ່ວ່າມັນເປັນ &lt;strong&gt;lazily evaluated&lt;/strong&gt;, ໝາຍຄວາມວ່າ value ທີ່ຖືກ return ຫຼັງຈາກທີ່ມີການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ຈະຖືກ compute ຫຼັງຈາກທີ່ເຮົາຮ້ອງຂໍເທົ່ານັ້ນ(ປະມານວ່າສັ່ງໃຫ້ເຮັດຈຶ່ງເຮັດ🫡). fucntion ປົກກະຕິຈະບໍ່ມີແບບນີ້ - value ທັງໝົດຈະຖືກ generate ໃຫ້ເຮົາໃນກໍລະນີທີ່ເຮົາຈຳເປັນຕ້ອງໃຊ້ໃນອານາຄົດ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YTyIUvFa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--HDINzSjh--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7b24mkp7io3gmnn8pzwa.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YTyIUvFa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--HDINzSjh--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7b24mkp7io3gmnn8pzwa.gif" alt="lazily evaluated" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ເທົ່າທີ່ຜ່ານມາມັນກໍ່ເບິ່ງຄືກັບ use cases ອື່ນໆ, ແຕ່ມັນຈະຊ່ວຍໃຫ້ເຮົາມີທາງເລືອກທີ່ຈະສາມາດ control ການ iterate datasets ທີ່ໃຫຍ່ໆໄດ້.&lt;/p&gt;

&lt;p&gt;ລອງຈິນຕະນາການເບິ່ງວ່າເຮົາມີ list ຂອງ book clubs📚, ເພື່ອໃຫ້ຕົວຢ່າງຂອງເຮົາງ່າຍ ແລະ ສັ້ນເຮົາຈຶ່ງມີ data ດັ່ງນີ້: ແຕ່ລະ book clubs ຈະມີ member ພຽງ 1 ຄົນ ແລະ ອ່ານປື້ມຫຼາຍຫົວທີ່ສະແດງໃນ &lt;code&gt;books&lt;/code&gt; array.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FJfFgUY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--xs97vroJ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8opapd1iddlgj1ljixje.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FJfFgUY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--xs97vroJ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8opapd1iddlgj1ljixje.png" alt="books array" width="800" height="903"&gt;&lt;/a&gt;&lt;br&gt;
ຕອນນີ້ເຮົາຕ້ອງການທີ່ຈະຫາ book ທີ່ມີ id ເທົ່າກັບ &lt;code&gt;ey812&lt;/code&gt;, ໃນການຄົ້ນຫາເຮົາອາດຈະໃຊ້ nested &lt;code&gt;for-loop&lt;/code&gt; ຫຼື &lt;code&gt;forEach&lt;/code&gt; helper, ແຕ່ນັ້ນກໍ່ໝາຍຄວາມວ່າເຮົາຍັງຄົງສາມາດ iterate data ໄດ້ເຖິງແມ່ນວ່າເຮົາຈະພົບຂໍ້ມູນທີ່ເຮົາຕ້ອງການແລ້ວກໍ່ຕາມ.&lt;br&gt;
ສິ່ງທີ່ຄັກກ່ຽວກັບ generator ໃນທີ່ນີ້ຄື: ມັນຈະບໍ່ເຮັດວຽກໄປເລື້ອຍໆຈົນກວ່າເຮົາຈະບອກໃຫ້ມັນເຮັດ-ໝາຍຄວາມວ່າເຮົາສາມາດປະເມີນ item ທີ່ຖືກ return ອອກມາໄດ້ ແລະ ຖ້າມັນເປັນ item ທີ່ເຮົາຕ້ອງການ ເຮົາກໍ່ບໍ່ຈຳເປັນທີ່ຈະຕ້ອງເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method. ເຮົາລອງມາເບິ່ງນຳກັນວ່າຈະເປັນແນວໃດ.&lt;/p&gt;

&lt;p&gt;ທຳອິດເຮົາຈະທຳການສ້າງ generator ທີ່ມີການ iterate &lt;code&gt;books&lt;/code&gt; array ຂອງແຕ່ລະ team member, ເຮົາຈະສົ່ງຄ່າ &lt;code&gt;books&lt;/code&gt; array ຂອງ team member ເຂົ້າໄປໃນ function ຈາກນັ້ນຈະມີການ iterate array ແລະ ທຳການ yield ແຕ່ລະ book&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3vY-PBkL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--VIKQMt8N--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vokf28crwuvbmksd57m5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3vY-PBkL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--VIKQMt8N--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vokf28crwuvbmksd57m5.png" alt="pass books array to generator" width="800" height="395"&gt;&lt;/a&gt;&lt;br&gt;
ຫຼັງຈາກທີ່ເຮົາໄດ້ generator ດ້ານເທິງມາແລ້ວ, ຕໍ່ໄປເຮົາຕ້ອງໄດ້ສ້າງອີກ generator ທີ່ iterate &lt;code&gt;clubMembers&lt;/code&gt; array. ເຊິ່ງໃນຈຸດນີ້ເຮົາບໍ່ໄດ້ສົນໃຈຂໍ້ມູນຂອງ member ເນື່ອງຈາກເຮົາຕ້ອງການທີ່ຈະ iterate ຂໍ້ມູນຂອງ &lt;code&gt;books&lt;/code&gt; ເທົ່ານັ້ນ. ຢູ່ໃນ &lt;code&gt;iterateMembers&lt;/code&gt; generator ເຮົາໄດ້ທຳການ yield &lt;code&gt;iterateBooks&lt;/code&gt; ໂດຍການສົ່ງ &lt;code&gt;books&lt;/code&gt; ຂອງ member ເຂົ້າໄປ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--02pO8bsJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--wOo9Qoct--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fy8mxxjj0uvs6rarm6mi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--02pO8bsJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--wOo9Qoct--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fy8mxxjj0uvs6rarm6mi.png" alt="yield iterateBooks" width="800" height="410"&gt;&lt;/a&gt;&lt;br&gt;
ມາຮອດຂັ້ນຕອນສຸດທ້າຍເຮົາຈະທຳການ iterate bookclubs, ເຊິ່ງມັນກໍ່ຄືກັບຕົວຢ່າງທີ່ຜ່ານມາ ເຮົາບໍ່ໄດ້ສົນໃຈຂໍ້ມູນຂອງ bookclubs, ແຕ່ເຮົາສົນໃຈພຽງ club members(ສະເພາະ books ຂອງແຕ່ລະ member). ເຮົາຈະທຳການ yield &lt;code&gt;iterateMembers&lt;/code&gt; ແລະ ທຳການສົ່ງ &lt;code&gt;clubMembers&lt;/code&gt; array ເຂົ້າໄປ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tAGb-B6P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--cPaacK9G--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/x1lor0omqw9t5k2kq4iv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tAGb-B6P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--cPaacK9G--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/x1lor0omqw9t5k2kq4iv.png" alt="pass club member to iterateMembers" width="800" height="391"&gt;&lt;/a&gt;&lt;br&gt;
ເພື່ອທີ່ຈະ iterate ທັງໝົດທີ່ຂຽນມາ, ເຮົາຕ້ອງການ generator object ທີ່ iterable ໂດຍການສົ່ງ &lt;code&gt;bookClub&lt;/code&gt; array ເຂົ້າໄປໃນ &lt;code&gt;iterateBookClubs&lt;/code&gt; generator, ຈາກນັ້ນເຮົາຈະທຳການເອີ້ນໃຊ້ໂດຍການສ້າງຕົວປ່ຽນ &lt;code&gt;it&lt;/code&gt; ຂຶ້ນມາເພື່ອເປັນ iterator.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0yBmTcpt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--fz9lH3an--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/omg23omwi8a1d7nn1it3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0yBmTcpt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--fz9lH3an--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/omg23omwi8a1d7nn1it3.png" alt="generator object" width="800" height="298"&gt;&lt;/a&gt;&lt;br&gt;
ຫຼັງຈາກຜ່ານຂັ້ນຕອນທຸກຢ່າງມາແລ້ວເຮົາຈະທຳການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ຈົນກວ່າເຮົາຈະໄດ້ຂໍ້ມູນຂອງ book ໂດຍທີ່ id ຂອງ book ຕ້ອງເທົ່າກັບ &lt;code&gt;ey812&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--f6VZA3gH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uenUfDOJ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/72ghm4ev6el3no9esk1l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--f6VZA3gH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uenUfDOJ--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/72ghm4ev6el3no9esk1l.gif" alt="call next method for book id ey812" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ຕອນນີ້ເຮົາບໍ່ຈຳເປັນຕ້ອງ iterate data ທັງໝົດເພື່ອເອົາຂໍ້ມູນຂອງ book, ແຕ່ເຮົາພຽງຫາຂໍ້ມູນເທົ່າທີ່ເຮົາຕ້ອງການຕົວຈິງແທນ. ສ່ວນການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ດ້ວຍຕົວເອງນັ້ນອາດຈະເປັນເລື່ອງທີ່ຂັດຫູຂັດຕາໄປແນ່, ດັ່ງນັ້ນເຮົາຈຶ່ງຕ້ອງໄດ້ສ້າງ function ໃນການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ຈົນກວ່າເຮົາຈະໄດ້ຂໍ້ມູນຕາມທີ່ເຮົາຕ້ອງການ.&lt;br&gt;
ເຮົາຈະທຳການສົ່ງ id ຂອງ book ເຂົ້າໄປໃນ &lt;code&gt;findBook&lt;/code&gt; function ເພື່ອທຳການຄົ້ນຫາ book ຕາມ id ທີ່ເຮົາສົ່ງເຂົ້າໄປ, ຖ້າພົບວ່າ id(ທີ່ສົ່ງເຂົ້າໄປ) ແລະ &lt;code&gt;value.id&lt;/code&gt; ຕົງກັນມັນກໍ່ຈະທຳການໂຍນ value ອອກມາ, ແຕ່ຖ້າທັງ 2 id ບໍ່ຕົງກັນມັນກໍ່ຈະທຳການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ອີກຄັ້ງແທນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dMZp2Ycw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--_XcgekW2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hxyeemfr3q8pqqotk51j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dMZp2Ycw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--_XcgekW2--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hxyeemfr3q8pqqotk51j.png" alt="findBook function" width="800" height="580"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QpDNp5QP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--oqOXhNFY--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/x1zh0ygt5yfq5vb2f5at.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QpDNp5QP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--oqOXhNFY--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/x1zh0ygt5yfq5vb2f5at.gif" alt="res of findBook function" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
ແນ່ນອນວ່າໃນຕົວຢ່າງທີ່ຍົກມາມັນຍັງເປັນຂໍ້ມູນທີ່ໜ້ອຍ, ແຕ່ລອງຄິດພາບເບິ່ງວ່າເຮົາມີ data ທີ່ຫຼາຍແຮງ ຫຼື ອາດຈະເປັນຂໍ້ມູນທີ່ຖືກ stream ເຂົ້າມາແລ້ວເຮົາຕ້ອງການທີ່ຈະແປງຂໍ້ມູນເຫຼົ່ານັ້ນ ຫຼື ອາດຈະຕ້ອງການຫາຂໍ້ມູນພຽງຢ່າງດຽວຈາກ datasets ໃຫຍ່ໆ. ໂດຍປົກກະຕິເຮົາຕ້ອງໄດ້ຖ້າໃຫ້ dataset ຂອງເຮົາພ້ອມກ່ອນເຮົາຈຶ່ງຈະເລີ່ມການແປງຂໍ້ມູນເຫຼົ່ານັ້ນໄດ້. ແຕ່ຖ້າໃຊ້ generator function ເຮົາສາມາດຂໍຂໍ້ມູນພຽງໜ້ອຍດຽວ, ກວດສອບຂໍ້ມູນ ແລະ value ຈະຖືກ generate ກໍ່ຕໍ່ເມື່ອເຮົາທຳການເອີ້ນໃຊ້ &lt;code&gt;next&lt;/code&gt; method ເທົ່ານັ້ນ.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;ອ້າງອີງ: &lt;a href="https://dev.to/lydiahallie/javascript-visualized-generators-and-iterators-e36"&gt;💡🎁 JavaScript Visualized: Generators and Iterators&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JavaScript EP5: Prototypal Inheritance🤰🏻👨‍👩‍👧‍👦</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Mon, 10 Apr 2023 09:27:32 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep5-prototypal-inheritance-g67</link>
      <guid>https://dev.to/phatsss/javascript-ep5-prototypal-inheritance-g67</guid>
      <description>&lt;p&gt;ຕອນທີ່ເຮົາຂຽນ JavaScript ເຊື່ອວ່າທຸກຄົນກໍ່ລ້ວນແລ້ວແຕ່ເຄີຍໃຊ້ບັນດາ built-in methods ກັນທັງນັ້ນເຊັ່ນ: &lt;code&gt;.length&lt;/code&gt;, &lt;code&gt;.split()&lt;/code&gt;, &lt;code&gt;.join()&lt;/code&gt;, etc. ບໍ່ວ່າຈະເປັນການໃຊ້ເພື່ອຈຸດປະສົງໃດໆ ຫຼື ໃຊ້ກັບປະເພດຂໍ້ມູນໃດໆກໍ່ຕາມເຊັ່ນ: &lt;code&gt;string&lt;/code&gt;,&lt;code&gt;array&lt;/code&gt;, &lt;code&gt;object&lt;/code&gt;. ແຕ່ຫຼາຍໆຄົນກໍ່ອາດຈະບໍ່ສົງໄສເລີຍວ່າບັນດາ methods ເຫຼົ່ານັ້ນມັນມາຈາກໄສ? ຢ່າບອກໃດວ່າມັນຄືເວດມົນ 🪄🤣. ອັນທີ່ຈິງຖ້າຈະໃຫ້ຕອບຄຳຖາມດ້ານເທິງແບບສັ້ນໆເລີຍ ຄຳຕອບກໍ່ຈະໄດ້ປະມານວ່າ: ຍ້ອນອີ່ຫຍັງບາງຢ່າງທີ່ເອີ້ນວ່າ &lt;strong&gt;prototypal inheritance&lt;/strong&gt;. ແຕ່ເຊື່ອບໍ່ວ່າໃນຕອນທີ່ຂຽນ code ເຮົາໃຊ້ມັນຫຼາຍກວ່າທີ່ຄິດອີກ, ສະນັ້ນເຮົາມາສຶກສາໃຫ້ເຂົ້າໃຈກ່ຽວກັບ prototypal inheritance ໃຫ້ຫຼາຍຂຶ້ນນຳກັນ.&lt;/p&gt;

&lt;p&gt;ສົມມຸດວ່າເຮົາມີເວັບທີ່ໃຫ້ຄົນທົ່ວໄປສາມາດເຂົ້າໄປເບິ່ງຂໍ້ມູນຂອງໝາໄດ້, ເຮົາມັກຈະຕ້ອງໄດ້ສ້າງ object ຫຼາຍໆອັນທີ່ເປັນ type ດຽວກັນ.&lt;/p&gt;

&lt;p&gt;ສຳລັບຂໍ້ມູນຂອງໝາ, ເຮົາຕ້ອງການ object ທີ່ເປັນຕົວແທນຂອງຂໍ້ມູນໝາໂຕນັ້ນ. ແທນທີ່ເຮົາຈະຂຽນ object ໃໝ່ທຸກໆຄັ້ງ ໃນທີ່ນີ້ເຮົາຈະໃຊ້ constructor function(ຮູ້ແຫຼະວ່າພາກັນຄິດຫຍັງຢູ່, ເລື່ອງຂອງ class ດຽວເຮົາຈະມາເວົ້າກັນອີກຕື່ມພາຍຫຼັງ)ເຊິ່ງເຮົາກໍ່ສາມາດສ້າງ instance ຂອງ Dog ໄດ້ດ້ວຍ keyword ໃໝ່ໄດ້ເຊັ່ນກັນ.&lt;/p&gt;

&lt;p&gt;ໝາທຸກໆໂຕຂອງເຮົາຈະມີຂໍ້ມູນດັ່ງນີ້: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;breed&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt; ແລະ function ທີ່ບອກວ່າໝາເຫົ່າຫຼືບໍ່ຄື &lt;code&gt;bark&lt;/code&gt;🐕.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OR_WHKKI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--pDfw39RK--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/caurw7uuk62htpldgtln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OR_WHKKI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--pDfw39RK--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/caurw7uuk62htpldgtln.png" alt="dog object" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເມື່ອເຮົາສ້າງ &lt;code&gt;Dog&lt;/code&gt; constructor function ສຳເລັດ, ມັນບໍ່ແມ່ນ object ດຽວທີ່ເຮົາຈະສ້າງ, ມັນຍັງມີ object ອື່ນທີ່ຖືກສ້າງໂດຍອັດຕະໂນມັດຄື: prototype. ໂດຍ default ແລ້ວ object ນີ້ບັນຈຸ constructor property ທີ່ອ້າງອີງເຖິງ original constructor function, ເຊິ່ງໃນກໍລະນີນີ້ແມ່ນ &lt;code&gt;Dog&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--abpUEOy5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--dWGIZ_zz--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9howj4i3zvlgun3svppp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--abpUEOy5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--dWGIZ_zz--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9howj4i3zvlgun3svppp.gif" alt="constructor function" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;prototype property ໃນ Dog constructor function ເປັນ non-enumerable(ນັບບໍ່ໄດ້) ໝາຍຄວາມວ່າມັນຈະບໍ່ສະແດງເມື່ອເຮົາ access ເຂົ້າ objects properties, ແຕ່ມັນຍັງມີຢູ່.&lt;/p&gt;

&lt;p&gt;ແລ້ວເປັນຫຍັງເຮົາຈຶ່ງມີ property object?, ກ່ອນອື່ນເຮົາມາສ້າງ dogs ຈັກໂຕສອງໂຕທີ່ເຮົາຕ້ອງການສະແດງ. ເພື່ອໃຫ້ເຂົ້າໃຈງ່າຍ, ເຮົາຈະສ້າງ dog1 ແລະ dog2 ເຊິ່ງ dog1 ມີຊື່ວ່າ Daisy ເປັນພັນລາບາດໍ ສີດຳສຸດໜ້າຮັກ ແລະ dog2 ຊື່ວ່າ Jack ເປັນພັນ ແຈັກຣັດເຊວ ສີຂາວທີ່ກ້າຫານພ້ອມບວກກັບທຸກຢ່າງ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sn6RLos---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--O_jSVpBB--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lyajz4lade30ci2koirq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sn6RLos---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--O_jSVpBB--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lyajz4lade30ci2koirq.png" alt="Dog Object" width="654" height="718"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເມື່ອເຮົາລອງ log ເບິ່ງ dog1 ຜ່ານ console ແລະ expand properties ຂອງມັນອອກມາເບິ່ງຈະໄດ້ດັ່ງນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1RJ3iwRr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--cA-2FOVV--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tt4yfoz8ckmxfofv3f9v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1RJ3iwRr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--cA-2FOVV--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tt4yfoz8ckmxfofv3f9v.gif" alt="dog1" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຮົາຈະເຫັນ properties ທີ່ເຮົາໄດ້ເພີ່ມເຂົ້າເຊັ່ນ: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;breed&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt; ແລະ &lt;code&gt;bark&lt;/code&gt;. ແຕ່ໆໆໆ ເຫັນຫຍັງບໍ່? ໄອ້ property &lt;code&gt;__proto__&lt;/code&gt; ຄືແບ້ອີ່ຫຍັງອີກລ່ະບາດນິ?🤯 ມັນ non-enumerable(ນັບບໍ່ໄດ້), ເຊິ່ງມັນກໍ່ໝາຍຄວາມວ່າໂດຍປົກກະຕິມັນຈະບໍ່ສະແດງເມື່ອເຮົາ get properties ໃນ object, ດຽວເຮົາມາຂະຫຍາຍຄວາມຈຸດນີ້ນຳກັນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cP0UOhPY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--zxO-eMV0--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dye57pcku5cfaz0er60c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cP0UOhPY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--zxO-eMV0--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dye57pcku5cfaz0er60c.gif" alt="__proto__" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ັມັນຄ້າຍຄືກັບ Dog.prototype object ເລີຍ, ແຕ່ເຮົາລອງເດົາເບິ່ງວ່າ &lt;code&gt;__proto__&lt;/code&gt; ແມ່ນເປັນການອ້າງອີງ Dog.prototype object🤔. ແຕ່ເຊື່ອບໍ່ວ່ານີ້ແມ່ນ &lt;strong&gt;prototypal inheritance&lt;/strong&gt; - ແຕ່ລະ instance ຂອງ constructor ສາມາດເຂົ້າເຖິງ prototype ຂອງ constructor ໄດ້🥶.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4dlukrnc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--FBGV--dx--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/t6kiav029gl2e0hv1xct.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4dlukrnc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--FBGV--dx--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/t6kiav029gl2e0hv1xct.gif" alt="dog properties object" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ແລ້ວມັນຄັກບ່ອນໃດ?🫣, ບາງເທື່ອເຮົາກໍ່ມີ properties ທີ່ instance ທັງໝົດໃຊ້ຮ່ວມກັນ. ຕົວຢ່າງໃນກໍລະນີນີ້ແມ່ນ &lt;code&gt;bark function&lt;/code&gt;, ເຊິ່ງທຸກໆ instance ແມ່ນມີຄືກັນທັງໝົດ ແລ້ວເປັນຫຍັງເຮົາຈຶ່ງຕ້ອງມາສ້າງ function ໃໝ່ທຸກຄັ້ງທີ່ເຮົາສ້າງ &lt;code&gt;dog&lt;/code&gt; ແຖມຍັງໃຊ້ memory ໃນແຕ່ລະຄັ້ງອີກ? ທັງໆທີ່ເຮົາສາມາດເພີ່ມ function ນີ້ລົງໄປໃນ &lt;code&gt;Dog.prototype&lt;/code&gt; object ໄດ້ເລີຍ😂.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ILXHX1aA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--2026kdwz--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/59nlnyqioosaowj09xn8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ILXHX1aA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--2026kdwz--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/59nlnyqioosaowj09xn8.gif" alt="add function to Dog.prototype" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເມື່ອເຮົາພະຍາຍາມທີ່ຈະ access property ໃນ instance ທຳອິດ engine ຈະຄົ້ນຫາຢູ່ local ເພື່ອເບິ່ງວ່າ property ໄດ້ຖືກ defined ໃນ object ເອງຫຼືບໍ່?. ແຕ່ຢ່າງໃດກໍ່ຕາມ ຖ້າມັນບໍ່ພົບ property ທີ່ເຮົາຕ້ອງການ access ນັ້ນ, engine ຈະທຳການເຂົ້າໄປເບິ່ງຢູ່ prototype ຜ່ານ &lt;code&gt;__proto__&lt;/code&gt; property.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hbbyxjvm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--gg5KU5nB--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fabyyjot1s78mttyzzk8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hbbyxjvm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--gg5KU5nB--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fabyyjot1s78mttyzzk8.gif" alt="access prototype" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ຕອນນີ້ມັນເປັນພຽງຂັ້ນຕອນດຽວ, ແຕ່ມັນຍັງມີອີກຫຼາຍຂັ້ນຕອນຕື່ມອີກ. ຖ້າຫາກ follow ຕາມຕົວຢ່າງທີ່ຜ່ານມາຈະສັງເກດເຫັນວ່າເຮົາບໍ່ໄດ້ເພີ່ມ property 1 ລາຍການ, ເມື່ອເຮົາ expand &lt;code&gt;__proto__&lt;/code&gt; object ທີ່ສະແດງ &lt;code&gt;Dog.prototype&lt;/code&gt;. &lt;code&gt;Dog.prototype&lt;/code&gt; ເປັນ object ໝາຍຄວາມວ່າທີ່ຈິງແລ້ວມັນເປັນ instance ຂອງ &lt;code&gt;Object constructor&lt;/code&gt; ສະແດງວ່າ &lt;code&gt;Dog.prototype&lt;/code&gt; ກໍ່ມີ &lt;code&gt;__proto__&lt;/code&gt; property, ເຊິ່ງເປັນການອ້າງອີງເຖິງ  &lt;code&gt;Object.prototype&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lSW9y1pi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--vJ7k8Gb3--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8vk5w6loliot818f2lcd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lSW9y1pi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--vJ7k8Gb3--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8vk5w6loliot818f2lcd.gif" alt="Object.prototype" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ໃນທີ່ສຸດເຮົາກໍ່ໄດ້ຄຳຕອບແລ້ວວ່າບັນດາ &lt;code&gt;built-in methods&lt;/code&gt; ມາຈາກໄສ, ມາຢູ່ໃນ prototype chain ນັ້ນເອງ🤩. ຖ້າໃຜຍັງບໍ່ໄດ້ຄຳຕອບກັບໄປອ່ານອີກຮອບເດີ 5555.&lt;/p&gt;

&lt;p&gt;ຕົວຢ່າງ: &lt;code&gt;.toString()&lt;/code&gt; method. ມັນຖືກ defined ຢູ່ local ໃນ &lt;code&gt;dog1&lt;/code&gt; object ບໍ່? ເທົ່າທີ່ເຫັນກະບໍ່ໃດລ່ະ😂 ຫຼື ມັນຖືກ defined ຢູ່ໃນ object &lt;code&gt;dog1.__proto__&lt;/code&gt; ແລ້ວມັນມີການອ້າງອີງເຖິງ &lt;code&gt;Dog.prototype&lt;/code&gt; ບໍ່? ບໍ່ໜ້າຈະແມ່ນເຊັ່ນກັນ, ແຕ່ມັນຖືກ defined ຢູ່ໃນ &lt;code&gt;Dog.prototype.__proto__&lt;/code&gt; ທີ່ອ້າງອີງເຖິງ &lt;code&gt;Object.prototype&lt;/code&gt; ພີ້ນ່ະ🤣.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NwMNZpHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--16IwaVkk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fpt5nndkbq5kau0nqeqj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NwMNZpHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--16IwaVkk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fpt5nndkbq5kau0nqeqj.gif" alt="Dog.prototype.__proto__" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ຕອນນີ້ເຮົາຫາກໍ່ໄດ້ໃຊ້ constructor functions (&lt;code&gt;function Dog() { ... }&lt;/code&gt;) ທີ່ຍັງເປັນວິທີຂຽນທີ່ຖືກຕ້ອງຢູ່ໃນພາສາ JavaScript, ແຕ່ມີວິທີທີ່ງ່າຍກວ່ານັ້ນໃນການໃຊ້ constructor functions ທີ່ເຮັດວຽກຮ່ວມກັນກັບ prototypes ຄື: &lt;code&gt;classes&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ການໃຊ້ classes ເປັນພຽງການປ່ຽນວິທີຂຽນເພື່ອໃຫ້ເຮົາໃຊ້ constructor functions ໄດ້ກະທັດຮັດ ແລະ ເຂົ້າໃຈງ່າຍຂຶ້ນເທົ່ານັ້ນ, ເຊິ່ງທຸກຢ່າງຍັງຄົງເຮັດວຽກປົກກະຕິ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ເຮົາຂຽນ classes ດ້ວຍ &lt;code&gt;class&lt;/code&gt; keyword. ໂດຍພື້ນຖານ class ຈະມີ &lt;code&gt;constructor&lt;/code&gt; function, ບັນດາ properties ທີ່ເຮົາຕ້ອງການເພີ່ມໃນ prototype ແມ່ນຖືກ defined ຢູ່ໃນ body ຂອງ classes.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TjcMZwI5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--3PePIjz5--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qnbqubcipqjl5pb3i8ds.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TjcMZwI5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--3PePIjz5--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qnbqubcipqjl5pb3i8ds.gif" alt="classes" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ອີກຂໍ້ດີຂອງການໃຊ້ class ກໍ່ຄືເຮົາສາມາດ &lt;code&gt;extend&lt;/code&gt; classes ອື່ນໆໄດ້.&lt;/p&gt;

&lt;p&gt;ເຮົາຕ້ອງການສະແດງໝາສາຍພັນຊິວາວາຫຼາຍໆໂຕ, ເພື່ອໃຫ້ຕົວຢ່າງຂອງເຮົາເຂົ້າໃຈງ່າຍ ເຮົາຈະສົ່ງ property &lt;code&gt;name&lt;/code&gt; ໄປ Dog class ແທນ &lt;code&gt;name&lt;/code&gt;,&lt;code&gt;breed&lt;/code&gt; ແລະ &lt;code&gt;color&lt;/code&gt;. ແຕ່ວ່າຊິວາວາຍັງຄົງມີສະກິວພິເສດຢູ່ຄື: ມັນເຫົ່າເກັ່ງແຖມຍັງສຽງແຫຼມໆນ້ອຍໆອີກ🤣 ແທນທີ່ມັນຈະເຫົ່າແບບດຸດັນເຣົ້າໃຈ(&lt;code&gt;Woof&lt;/code&gt;), ຖ້າເປັນຊິວາວາອາດຈະເປັນ &lt;code&gt;small woof&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;ໃນ &lt;code&gt;extended class&lt;/code&gt; ເຮົາສາມາດ access ເຂົ້າໄປ parent class' constructor ໂດຍໃຊ້ &lt;code&gt;super&lt;/code&gt; keyword. ສ່ວນບັນດາ arguments ທີ່ parent class' constructor ຕ້ອງການ ເຮົາຕ້ອງສົ່ງຄ່າໄປ super, ເຊິ່ງໃນກໍລະນີນີ້ແມ່ນ &lt;code&gt;name&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0w97Yno6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--Fitn1c9K--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tx25dar3duqo0z2bpfam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0w97Yno6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--Fitn1c9K--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/tx25dar3duqo0z2bpfam.png" alt="Dog Class" width="800" height="994"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;myPet&lt;/code&gt; ສາມາດ access ເຂົ້າໄດ້ທັງ &lt;code&gt;Chihuahua.prototype&lt;/code&gt; ແລະ &lt;code&gt;Dog.prototype&lt;/code&gt; (ແລະ &lt;code&gt;Object.prototype&lt;/code&gt; ໂດຍອັດຕະໂນມັດ, ເນື່ອງຈາກ &lt;code&gt;Dog.prototype&lt;/code&gt; ເປັນ object).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jlGO1w43--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--WOeqUeM3--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qija16dju8t5j1ksy0ps.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jlGO1w43--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--WOeqUeM3--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qija16dju8t5j1ksy0ps.gif" alt="prototypal inheritance" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເນື່ອງຈາກ &lt;code&gt;Chihuahua.prototype&lt;/code&gt; ມີ &lt;code&gt;smallBark&lt;/code&gt; function ແລະ &lt;code&gt;Dog.prototype&lt;/code&gt; ມີ &lt;code&gt;bark&lt;/code&gt; function ເຮົາຈຶ່ງສາມາດ access ໄດ້ທັງ &lt;code&gt;smallBark&lt;/code&gt; ແລະ &lt;code&gt;bark&lt;/code&gt; ໃນ &lt;code&gt;myPet&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;ເຮົາລອງຈິນຕະນາການເບິ່ງວ່າ prototype chain ບໍ່ໄດ້ access ໄປໄດ້ຕະຫຼອດ. ຖ້າຫາກວ່າມີ object ທີ່ເປັນ prototype ເທົ່າກັບຄ່າ &lt;code&gt;null&lt;/code&gt;, ໃນກໍລະນີນີ້ແມ່ນ &lt;code&gt;Object.prototype&lt;/code&gt; object ຖ້າເຮົາພະຍາຍາມ access property ທີ່ມັນບໍ່ພົບຢູ່ local ຫຼື prototype chain ມັນຈະ return ຄ່າ &lt;code&gt;undefined&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WfI4uj1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s---EseK2fk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1905zxijp45soy0jzle2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WfI4uj1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s---EseK2fk--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1905zxijp45soy0jzle2.gif" alt="prototype chain equal null" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;ເຖິງແມ່ນວ່າໃນບົດຄວາມນີ້ໄດ້ອະທິບາຍທຸກຢ່າງກ່ຽວກັບການໃຊ້ constructor functions ແລະ classes ໄປແລ້ວ, ແຕ່ມັນກໍ່ຍັງມີອີກວິທີອື່ນເຊັ່ນກັນໃນການທີ່ຈະເພີ່ມ prototypes ໃນ objects ເຊັ່ນ: &lt;code&gt;Object.create&lt;/code&gt; method, ເຊິ່ງ method ນີ້ເຮົາສາມາດສ້າງ object ໃໝ່ ແລະ ສາມາດລະບຸໄດ້ເລີຍວ່າ prototype ຂອງ object ເຮົາຈະມີໜ້າຕາແບບໃດ.&lt;/p&gt;

&lt;p&gt;ວິທີການແມ່ນເຮົາຈະທຳການສົ່ງ object ໃນຮູບແບບຂອງ argument ໄປ &lt;code&gt;Object.create&lt;/code&gt; method, object ທີ່ເຮົາສົ່ງເຂົ້າໄປຈະເປັນ prototype ຂອງ object ທີ່ເຮົາສ້າງ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JRwuPIpx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uw9DJFU0--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kbwwsn1fd4gngd05tm9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JRwuPIpx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--uw9DJFU0--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kbwwsn1fd4gngd05tm9a.png" alt="Object.create" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຮົາມາລອງ log ເບິ່ງ object ທີ່ເຮົາຫາກໍ່ສ້າງລອງເບິ່ງ:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3s1OEmEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--9sWtvaRG--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6zzt8zpy85gtitxmpwi9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3s1OEmEO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--9sWtvaRG--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6zzt8zpy85gtitxmpwi9.gif" alt="log Object.create" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເຮົາບໍ່ໄດ້ທຳການເພີ່ມ properties ໃດໆເຂົ້າໄປໃນ &lt;code&gt;me&lt;/code&gt; opbject, ມັນມີພຽງ &lt;code&gt;__proto__&lt;/code&gt; property ທີ່ non-enumerable(ບໍ່ສາມາດນັບໄດ້)ເທົ່ານັ້ນ. &lt;code&gt;__proto__&lt;/code&gt; property ມີການອ້າງອີງໄປຍັງ object ທີ່ເຮົາໄດ້ທຳການ defined ໃຫ້ເປັນ prototype. &lt;code&gt;person&lt;/code&gt; object ທີ່ມີ &lt;code&gt;name&lt;/code&gt; ແລະ &lt;code&gt;age&lt;/code&gt; ເປັນ property, ເນື່ອງຈາກ &lt;code&gt;person&lt;/code&gt; object ເປັນ object ເຊິ່ງ value ຂອງ &lt;code&gt;__proto__&lt;/code&gt; property ໃນ &lt;code&gt;person&lt;/code&gt; object ແມ່ນ &lt;code&gt;Object.prototype&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;ອ້າງອີງ: &lt;a href="https://dev.to/lydiahallie/javascript-visualized-prototypal-inheritance-47co"&gt;🎉👨‍👩‍👧‍👧 JavaScript Visualized: Prototypal Inheritance&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JavaScript EP4: JavaScript Engine 🛠️⚙️</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Thu, 06 Apr 2023 17:03:21 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep4-javascript-engine-2jol</link>
      <guid>https://dev.to/phatsss/javascript-ep4-javascript-engine-2jol</guid>
      <description>&lt;p&gt;ໃນ EP ນີ້ເຮົາຈະມາເວົ້າເຖິງ JS Engine ວ່າມັນເຮັດວຽກຈັ່ງໃດ, ເພື່ອໃຫ້ເຮົາເຫັນພາບຂະບວນການເບື້ອງຫຼັງຂອງ JS ຫຼາຍຂຶ້ນ. ເຮົາເຄີຍສົງໄສບໍ່ວ່າບັນດາ machine ມັນເຂົ້າໃຈ code ທີ່ເຮົາຂຽນໄດ້ຈັ່ງໃດ?. JavaScript Developer ບໍ່ຈຳເປັນຕ້ອງຈັດການກັບ compilers ດ້ວຍຕົວເອງ, ເຊິ່ງນັກພັດທະນາມືໃໝ່ຫຼາຍໆຄົນກໍ່ບໍ່ໄດ້ສົນໃຈເລື່ອງນີ້ເລີຍ ແຕ່ມັນຍິ່ງເປັນການດີຖ້າເຮົາຈະສຶກສາ ແລະ ມີຄວາມຮູ້ພື້ນຖານກ່ຽວກັບ JavaScript Engine ແລະ ເບິ່ງວ່າມັນຈະຈັດການກັບ code ທີ່ເປັນ human-friendly ແລະ ປ່ຽນເປັນສິ່ງທີ່ machine ເຂົ້າໃຈ🚀.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ຕົວຢ່າງທີ່ໃຊ້ໃນບົດຄວາມນີ້ແມ່ນໃຊ້ NodeJS ທີ່ based on the V8 Engine ແລະ ໃຊ້ Browser ທີ່ເປັນ Chromium-based.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;HTML parser ຈະພົບ &lt;code&gt;script&lt;/code&gt; tag(&lt;code&gt;&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;)ທີ່ມີການລະບຸ JS source(ອາດຈະຢູ່ໃນ &lt;code&gt;script&lt;/code&gt; tag ຫຼື import ມາຈາກໄຟລ໌ນອກກໍ່ໄດ້). code ທີ່ຢູ່ໃນນັ້ນຈະຖືກ load ຈາກທຸກແຫຼ່ງທີ່ມາເຊັ່ນ: &lt;strong&gt;network&lt;/strong&gt;,&lt;strong&gt;cache&lt;/strong&gt; ແລະ &lt;strong&gt;service worker&lt;/strong&gt; ທີ່ຖືກຕິດຕັ້ງໄວ້ແລ້ວ. response ທີ່ໄດ້ຈາກ requested script ແມ່ນຈະຢູ່ໃນຮູບແບບ &lt;strong&gt;stream of bytes&lt;/strong&gt; ທີ່ຈະມີ &lt;strong&gt;byte stream decoder&lt;/strong&gt; ເຮັດໜ້າທີ່ໃນການຖອດລະຫັດ stream of bytes ຫຼັງຈາກມັນໂຫຼດສຳເລັດ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5iIX9neE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--Xs5OQmGX--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pv4y4w0doztvmp8ei0ki.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5iIX9neE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--Xs5OQmGX--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/pv4y4w0doztvmp8ei0ki.gif" alt="stream of bytes" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;byte stream decoder ຈະທຳການສ້າງ &lt;strong&gt;token&lt;/strong&gt; ຂຶ້ນມາຫຼັງຈາກທີ່ທຳການຖອດລະຫັດ stream of bytes ສຳເລັດ. ຕົວຢ່າງ, &lt;code&gt;0066&lt;/code&gt; ທຳການ decode ໄດ້ &lt;code&gt;f&lt;/code&gt;, &lt;code&gt;0075&lt;/code&gt; ໄດ້ &lt;code&gt;u&lt;/code&gt;, &lt;code&gt;006e&lt;/code&gt; ໄດ້ &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;0063&lt;/code&gt; ໄດ້ &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;0074&lt;/code&gt; ໄດ້ &lt;code&gt;t&lt;/code&gt;, &lt;code&gt;0069&lt;/code&gt; ໄດ້ &lt;code&gt;i&lt;/code&gt;, &lt;code&gt;006f&lt;/code&gt; ໄດ້ &lt;code&gt;o&lt;/code&gt;, ແລະ &lt;code&gt;006e&lt;/code&gt; ໄດ້ &lt;code&gt;n&lt;/code&gt; ຕາມດ້ວຍ white space. ເບິ່ງຄືກັບວ່າເຮົາຂຽນ &lt;code&gt;function&lt;/code&gt; ເຊິ່ງຄຳນີ້ກໍ່ເປັນ reserved keyword ຢູ່ໃນ JavaScript, ເຊິ່ງມັນຈະສ້າງ token ຂຶ້ນມາ ແລະ ສົ່ງໄປທີ່ parser(ແລະ pre-parser, ຈະອະທິບາຍພາຍຫຼັງ). ຂະບວນການທີ່ຍົກຕົວຢ່າງມາແມ່ນຈະເກີດຂຶ້ນກັບ byte stream ທີ່ເຫຼືອເຊັ່ນກັນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ucS74BAv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--ID8wDIAy--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bic727jhzu0i8uep8v0k.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ucS74BAv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--ID8wDIAy--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bic727jhzu0i8uep8v0k.gif" alt="decode the bytes into tokens" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;ຕົວ engine ຈະໃຊ້ parser 2 ຕົວຄື: &lt;strong&gt;pre-parser&lt;/strong&gt; ແລະ &lt;strong&gt;parser&lt;/strong&gt;. ເພື່ອຫຼຸດເວລາໃນການໂຫຼດໜ້າເວັບ, engine ຈະພະຍາຍາມຫຼີກລ່ຽງການ parsing code ທີ່ບໍ່ຈຳເປັນໃຫ້. pre-parser ຈະ handles code ທີ່ອາດຈະໄດ້ໃຊ້ໄວ້ ໃນຂະນະທີ່ຕົວ parser ຈະ handles code ທີ່ຈຳເປັນ. ຖ້າຫາກ function ບາງຢ່າງຖືກເອີ້ນໃຊ້ຫຼັງຈາກທີ່ user ກົດປຸ່ມ,​ ມັນກໍ່ບໍ່ຈຳເປັນທີ່ code ຈະຖືກ compile ໃນທັນທີພຽງເພື່ອໂຫຼດໜ້າເວັບຢ່າງດຽວ. ແຕ່ຖ້າຫາກ user ກົດປຸ່ມ ແລະ ມີການ require code ບາງສ່ວນ, ມັນຈະຖືກສົ່ງໄປ parser.&lt;/p&gt;

&lt;p&gt;Parser ຈະທຳການສ້າງ node ຕາມ token ທີ່ໄດ້ຮັບຈາກ byte stream decoder, ຈາກນັ້ນມັນຈະສ້າງ Abstract Syntax Tree ຫຼື AST ດ້ວຍ node ເຫຼົ່ານັ້ນ 🌲🌳.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EnXRkKbO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--6IHw1BUH--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/sgr7ih6t7zm2ek28rtg6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnXRkKbO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--6IHw1BUH--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/sgr7ih6t7zm2ek28rtg6.gif" alt="Abstract syntax tree" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;ຕໍ່ມາຈະເປັນໜ້າທີ່ຂອງ &lt;strong&gt;interpreter&lt;/strong&gt;, ເຊິ່ງ interpreter ຈະດຳເນີນການຜ່ານ AST ແລະ ທຳການສ້າງ &lt;strong&gt;byte code&lt;/strong&gt; ໂດຍອີງຕາມຂໍ້ມູນທີ່ AST ມີ. ເມື່ອ byte code ຖືກສ້າງສຳເລັດແລ້ວ, AST ຈະຖືກລຶບ ແລະ ລ້າງພື້ນທີ່ໜ່ວຍຄວາມຈຳ(memory space) ຫຼັງຈາກນັ້ນເຮົາກໍ່ມີ byte code ທີ່ machine ເຂົ້າໃຈແລ້ວ 🚀.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hFLiMoVk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--HlXdsZRx--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i5f0vmcjnkhireehicyn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hFLiMoVk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--HlXdsZRx--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i5f0vmcjnkhireehicyn.gif" alt="generate byte code" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;ເຖິງ byte code ຈະໄວຢູ່ກໍ່ຕາມ, ແຕ່ມັນຍັງໄວກວ່ານີ້ໄດ້ອີກ. ໃນຂະນະທີ່ byte code ນີ້ເຮັດວຽກ, ຂໍ້ມູນຕ່າງໆຈະຖືກ generate ຂຶ້ນ, ເຊິ່ງມັນຈະສາມາດ detect ໄດ້ວ່າພຶດຕິກຳໃດເກີດຂຶ້ນເລື້ອຍໆ ແລະ ປະເພດຂອງ data ຈະຖືກນຳມາໃຊ້. ບາງເທື່ອເຮົາກໍ່ເອີ້ນໃຊ້ function ເປັນສິບໆຮອບ, ເຊິ່ງໃນຈຸດນີ້ເຮົາຈະທຳການ optimize ເພື່ອໃຫ້ມັນເຮັດວຽກໄດ້ໄວ້ຂຶ້ນ.&lt;br&gt;
byte code ແລະ type feedback ທີ່ຖືກ generate ຂຶ້ນແມ່ນຈະຖືກສົ່ງໄປ &lt;strong&gt;optimizing compiler&lt;/strong&gt; ພ້ອມໆກັນ. optimizing compiler ຈະນຳທັງ 2 ຢ່າງນັ້ນມາທຳການ optimized ແລະ generate ອອກມາເປັນ machine code.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pRZSg0Wj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--gsKbgaq7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ongt4qftovd82sp2vihk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pRZSg0Wj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--gsKbgaq7--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ongt4qftovd82sp2vihk.gif" alt="optimizing compiler" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;JavaScript ເປັນ dynamic type language, ໝາຍຄວາມວ່າ type ຂອງ data ສາມາດປ່ຽນແປງໄດ້ຕະຫຼອດເວລາ. ຖ້າຫາກ JS Engine ຕ້ອງກວດສອບ data type ຢູ່ຕະຫຼອດເວລາ(ແຕ່ໃນຂະບວນການພັດທະນາ, ການໃຊ້ data type ແມ່ນຈະເຮັດໃຫ້ການພັດທະນາມີປະສິດທິພາບຫຼາຍ-ແນະນຳໄປເບິ່ງ TypeScript).&lt;/p&gt;

&lt;p&gt;ເພື່ອຫຼຸດເວລາທີ່ໃຊ້ໃນການ interpret code. ໃນຂະນະທີ່ run byte code, machine code ທີ່ຖືກ optimized ແລ້ວຈະ handle ສະເພາະ case ທີ່ engine ເຄີຍເຫັນມາກ່ອນເທົ່ານັ້ນ. ຖ້າເຮົາໃຊ້ code ບາງສ່ວນທີ່ມັນການ return data type ດຽວກັນຊ້ຳໆ, machine code ທີ່ຖືກ optimized ແລ້ວມັນສາມາດນຳມາໃຊ້ໃໝ່ເພື່ອເພີ່ມຄວາມໄວໄດດ້ຕື່ມອີກ. ແຕ່ເຖິງຢ່າງໃດກໍ່ຕາມ, ເນື່ອງຈາກ JavaScript ຖືກອອກແບບມາໃຫ້ເປັນ dynamic type ມັນອາດຈະມີບາງເຫດການທີ່ວ່າ code ບາງສ່ວນທີ່ຄືກັນແຕ່ມັນ return ຄົນລະ data type ອອກມາ. ຖ້າເກີດເຫດການແບບນີ້ຂຶ້ນ machine code ຈະທຳການ de-optimized ແລະ engine ຈະທຳການກັບໄປ interpreting ເພື່ອ generate byte code ໃໝ່.&lt;/p&gt;

&lt;p&gt;ສົມມຸດວ່າເຮົາໄດ້ເອີ້ນໃຊ້ບາງ function ເປັນຈຳນວນ 100 ຄັ້ງ ແລະ ມັນຈະ return ຄ່າເດີມມາສະເໝີ, ມັນຈະຖືວ່າມັນຈະທຳການ return ຄ່າເດີມມາຖ້າຫາກເຮົາເອີ້ນໃຊ້ຮອບທີ 101.&lt;/p&gt;

&lt;p&gt;ຖ້າຍັງງົງມາເບິ່ງອີກຕົວຢ່າງ: ສົມມຸດວ່າເຮົາມີ sum function ດັ່ງຕໍ່ໄປນີ້, ເຊິ່ງມັນຈະຖືກເອີ້ນໃຊ້ດ້ວຍການປ້ອນ arguments ທີ່ເປັນຄ່າຕົວເລກທຸກຄັ້ງ:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kS_ienM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s---hJ4L3Hm--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dhiaau4lo3n457yqud4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kS_ienM7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s---hJ4L3Hm--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dhiaau4lo3n457yqud4o.png" alt="sum function" width="612" height="490"&gt;&lt;/a&gt;&lt;br&gt;
ໃນ function ດ້ານເທິງມັນຈະ return ຄ່າທີ່ເປັນຕົວເລກອອກມາຄື &lt;code&gt;3&lt;/code&gt;, ຄັ້ງຕໍ່ໄປທີ່ເຮົາເອີ້ນໃຊ້ມັນຈະຖືວ່າເຮົາກຳລັງເອີ້ນໃຊ້ອີກຄັ້ງດ້ວຍ arguments ທີ່ເປັນຕົວເລກ 2 ຄ່າ.&lt;/p&gt;

&lt;p&gt;ຖ້າມັນເປັນແບບນັ້ນກໍ່ບໍ່ຈຳເປັນຕ້ອງຄົ້ນຫາແບບ dynamic ແລະ ສາມາດ re-use machine code ທີ່ຖືກ optimized ໄດ້ເລີຍ. ແຕ່ຖ້າບໍ່ເປັນແບບນັ້ນ ມັນກໍ່ຈະ revert ໄປເປັນ original byte code ຂອງ machine code ທີ່ຖືກ optimized.&lt;/p&gt;

&lt;p&gt;ຕົວຢ່າງ: ຄັ້ງຕໍ່ໄປທີ່ເຮົາເອີ້ນໃຊ້ເຮົາຈະສົ່ງຄ່າທີ່ເປັນ string ແທນຕົວເລກ, ເນື່ອງຈາກ JavaScript ເປັນ dynamic type ເຮົາຈຶ່ງສາມາດເຮັດແບບນີ້ໄດ້ໂດຍທີ່ບໍ່ມີ Error ໃດໆ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iIBWdArz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--GtrihoCc--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zugnjsg813urbj6vr4iy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iIBWdArz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--GtrihoCc--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zugnjsg813urbj6vr4iy.png" alt="pass string to ssum function" width="612" height="490"&gt;&lt;/a&gt;&lt;br&gt;
ໝາຍຄວາມວ່າເລກ &lt;code&gt;2&lt;/code&gt; ຈະຖືກບີບໃຫ້ເປັນ string ແລະ function ຈະ return ຄ່າ &lt;code&gt;"12"&lt;/code&gt; ອອກມາແທນ. ທີ່ເປັນແບບນີ້ກໍ່ຍ້ອນມັນກັບໄປ execute byte code ທີ່ຖືກ interpreted ແລ້ວ ແລະ ທຳການ update type ກັບໄປ.&lt;/p&gt;




&lt;p&gt;ອ້າງອີງ: &lt;a href="https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf"&gt;🚀⚙️ JavaScript Visualized: the JavaScript Engine&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JavaScript EP3: Scope (Chain)⛓️🚧</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Mon, 03 Apr 2023 13:20:47 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep3-scope-chain-43ej</link>
      <guid>https://dev.to/phatsss/javascript-ep3-scope-chain-43ej</guid>
      <description>&lt;p&gt;ມາຮອດ ep ນີ້, ເຊື່ອວ່າຫຼາຍໆຄົນກໍ່ອາດຈະເຄີຍຂຽນ JS ບໍ່ຫຼາຍກໍ່ໜ້ອຍ, ແຕ່ຈະພະຍາຍາມຍົກຕົວຢ່າງທີ່ງ່າຍ ແລະ ເຂົ້າໃຈໄດ້ພາຍໃນ 3 ວິນາທີ🥹🥹🥹.&lt;/p&gt;

&lt;p&gt;ເຮົາມາເບິ່ງ code ກັນກ່ອນເລີຍ:&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lydia&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;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;San Francisco&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getPersonInfo&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sarah&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;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; and lives in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="nx"&gt;getPersonInfo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ຈາກ code ຈະເຫັນວ່າເຮົາໄດ້ທຳການ invoke &lt;code&gt;getPersonInfo&lt;/code&gt; function ທີ່ມີການ return ຄ່າເປັນ string ອອກມາ, ໃນນັ້ນປະກອບດ້ວຍຕົວປ່ຽນ &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt; ແລະ &lt;code&gt;city&lt;/code&gt;. ຜົນທີ່ໄດ້ຈາກ code ດ້ານເທິງແມ່ນ &lt;code&gt;Sarah is 22 and lives in San Francisco&lt;/code&gt;, ແຕ່ໃນ &lt;code&gt;getPersonInfo&lt;/code&gt; function ບໍ່ໄດ້ບັນຈຸຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt; ແລ້ວມັນຮູ້ຈັກຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt; ໄດ້ແນວໃດ?🤔.&lt;/p&gt;

&lt;p&gt;ທຳອິດຈະມີການຈັດການພື້ນທີ່ memory ໃນຫຼາຍໆ context ທີ່ແຕກຕ່າງກັນ, ເຮົາມີ &lt;strong&gt;global context&lt;/strong&gt; ເປັນ default(&lt;code&gt;window&lt;/code&gt; ໃນ browser ແລະ &lt;code&gt;global&lt;/code&gt; ໃນ Node) ແລະ &lt;strong&gt;local context&lt;/strong&gt; ສຳລັບ &lt;code&gt;getPersonInfo&lt;/code&gt; function ທີ່ຖືກ invoke. ແຕ່ລະ context ກໍ່ຈະມີ &lt;strong&gt;scope chain&lt;/strong&gt; ເຊັ່ນກັນ.&lt;/p&gt;

&lt;p&gt;ສຳລັບ &lt;code&gt;getPersonInfo&lt;/code&gt; function, scope chain ຈະມີຂະບວນການປະມານນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_coSNT13--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--57Tstr0c--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/89b9buizhevs0jf6djyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_coSNT13--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--57Tstr0c--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/89b9buizhevs0jf6djyn.png" alt="scope chain" width="880" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ໂດຍພື້ນຖານແລ້ວ scope chain ເປັນ "chain of references" ໄປຫາ object ທີ່ມີການອ້າງອີງເຖິງ values(ແລະ scopes ອື່ນໆ)ທີ່ຖືກອ້າງອີງຢູ່ໃນ execution context. scope chain ຖືກສ້າງຂຶ້ນຕອນທີ່ execution context ຖືກສ້າງຂຶ້ນ, ໝາຍຄວາມວ່າມັນຖືກສ້າງຕອນ runtime.&lt;/p&gt;

&lt;p&gt;ເຖິງຢ່າງໃດກໍ່ຕາມ, ເຮົາຈະຍັງບໍ່ເວົ້າເຖິງ activation object ຫຼື execution contexts ໃນບົດຄວາມນີ້ເທື່ອ(ໃນບົດຄວາມນີ້ເຮົາມາໂຟກັສທີ່ scope ກັນກ່ອນ). ດັ່ງຕົວຢ່າງດ້ານລຸ່ມ key/value ທີ່ຢູ່ນຳ execution contexts ຈະສະແດງເຖິງການອ້າງອີງທີ່ scope chain ມີຕໍ່ຕົວປ່ຽນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--whJ1qeix--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--3L9mEScA--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/iala2et7bg9bgdj4c2lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--whJ1qeix--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--3L9mEScA--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/iala2et7bg9bgdj4c2lg.png" alt="key/value" width="880" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;scope chain ຂອງ global execution context ມີການອ້າງອີງເຖິງ 3 ຕົວປ່ຽນຄື: &lt;code&gt;name&lt;/code&gt; ໂດຍມີຄ່າ &lt;code&gt;Lydia&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt; ມີຄ່າ &lt;code&gt;21&lt;/code&gt; ແລະ &lt;code&gt;city&lt;/code&gt; ມີຄ່າ &lt;code&gt;San Francisco&lt;/code&gt;. ໃນ local context ເຮົາມີການອ້າງອີງເຖິງ 2 ຕົວປ່ຽນຄື: &lt;code&gt;name&lt;/code&gt; ມີຄ່າ &lt;code&gt;Sarah&lt;/code&gt; ແລະ &lt;code&gt;age&lt;/code&gt; ມີຄ່າ &lt;code&gt;22&lt;/code&gt;.&lt;br&gt;
ເມື່ອເຮົາ access ເຂົ້າເຖິງຕົວປ່ຽນທີ່ຢູ່ໃນ &lt;code&gt;getPersonInfo&lt;/code&gt;, JS Engine ຈະທຳການກວດຢູ່ local scope chain ກ່ອນ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r1fboVzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--e_017_sT--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xn17f0t54acz8tiq7122.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r1fboVzT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--e_017_sT--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xn17f0t54acz8tiq7122.gif" alt="local scope chain" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;local scope chain ມີການອ້າງອີງເຖິງ &lt;code&gt;name&lt;/code&gt; ແລະ &lt;code&gt;age&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt; ມີຄ່າ &lt;code&gt;Sarah&lt;/code&gt; ແລະ &lt;code&gt;age&lt;/code&gt; ມີຄ່າ &lt;code&gt;22&lt;/code&gt;. ເຮົາມາລອງສັງເກດເບິ່ງວ່າຖ້າເຮົາ access ຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt; ຈະເປັນຈັ່ງໃດ?🫣&lt;br&gt;
ເພື່ອຫາ value ຂອງຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt;, JS Engine ຈະທຳການລົງໄປຄົ້ນຫາຕາມ scope chain ໝາຍຄວາມວ່າຖ້າມັນບໍ່ພົບ value ໃນ local scope chain ມັນກໍ່ຈະທຳການຫາຢູ່ໃນ outer scope(scope ທີ່ນອກ local scope)ທີ່ local scope ໄດ້ມີການອ້າງອີງເຖິງ ໃນຕົວຢ່າງດ້ານລຸ່ມຈະແມ່ນ &lt;strong&gt;global object&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zm5gDUbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--uE5KEpLT--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/z9iclg23rmbpts7meoq6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zm5gDUbD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--uE5KEpLT--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/z9iclg23rmbpts7meoq6.gif" alt="local scope" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ໃນ global context ເຮົາໄດ້ປະກາດຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt; ມີຄ່າ &lt;code&gt;San Francisco&lt;/code&gt;, ດັ່ງນັ້ນ ຈຶ່ງມີການອ້າງອີງເຖິງຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt;. ຕອນນີ້ເຮົາມີ value ຂອງແຕ່ລະຕົວປ່ຽນແລ້ວຈຶ່ງເຮັດໃຫ້ &lt;code&gt;getPersonInfo&lt;/code&gt; function ສາມາດ return ຄ່າທີ່ເປັນ string ອອກມາໄດ້ ແລະ ຜົນທີ່ໄດ້ແມ່ນ &lt;code&gt;Sarah is 22 and lives in San Francisco&lt;/code&gt;.&lt;/p&gt;



&lt;p&gt;ເຮົາສາມາດລົງໄປຊັ້ນລຸ່ມຂອງ scope chain ໄດ້, ແຕ່ບໍ່ສາມາດຂຶ້ນມາຊັ້ນເທິງຂອງ scope chain ໄດ້ ຫຼື ຈະເອີ້ນວ່າອອກນອກ scope ໄດ້ແຕ່ບໍ່ສາມາດເຂົ້າໄປໃນ scope ແບບນີ້ກໍ່ໄດ້ເຊັ່ນກັນ. ຖ້າຍັງງົງກໍ່ໄປເບິ່ງຕົວຢ່າງນຳກັນເລີຍ😵‍💫.&lt;br&gt;
ໃນຕົວຢ່າງຈະອະທິບາຍໃນລັກສະນະຂອງຂະບວນການໄຫຼຂອງນ້ຳຕົກ(ໄຫຼຈາກເທິງລົງລຸ່ມ).&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OvHpAW6l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--mJn1OY2F--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/doq46yc6nuiam51evy44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OvHpAW6l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--mJn1OY2F--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/doq46yc6nuiam51evy44.png" alt="waterfall" width="880" height="373"&gt;&lt;/a&gt;&lt;br&gt;
ຫຼື ກໍລະນີທີ່ມີ function ຊ້ອນກັນອີກກໍ່ຈະມີໜ້າຕາ ແລະ ຊົງຜົມປະມານນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MfnETXno--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--ymRwRgkB--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rece2zj4pb4w1fn56q5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MfnETXno--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--ymRwRgkB--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rece2zj4pb4w1fn56q5k.png" alt="deeper waterfall" width="880" height="518"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;ເຮົາລອງມາສຶກສາເບິ່ງ code ຕົວຢ່າງນີ້ໄປນຳກັນ&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CAN5Eaom--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--HQ8cmkNI--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0z6342b72f3n6v6ufafk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CAN5Eaom--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--HQ8cmkNI--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0z6342b72f3n6v6ufafk.png" alt="example code" width="880" height="490"&gt;&lt;/a&gt;&lt;br&gt;
ມັນຄ້າຍຄືກັນກັບຕົວຢ່າງຕັ້ງແຕ່ທຳອິດແທບຈະທຸກຢ່າງ, ແຕ່ເຖິງຢ່າງໃດກໍຕາມມັນມີຈຸດແຕກຕ່າງໃຫຍ່ໆເລີຍກໍ່ຈະແມ່ນ: ເຮົາໄດ້ປະກາດຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt; ຢູ່ໃນ &lt;code&gt;getPersonInfo&lt;/code&gt; function ແລະ ບໍ່ຢູ່ໃນ global scope. ໃນທີ່ນີ້ເຮົາບໍ່ໄດ້ invoke &lt;code&gt;getPersonInfo&lt;/code&gt; function, ດັ່ງນັ້ນ ມັນຈະບໍ່ມີການສ້າງ local context ເຊັ່ນກັນ. ເຮົາລອງ access ເຖິງ value ຂອງ &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt; ແລະ &lt;code&gt;city&lt;/code&gt; ໃນ global context ດັ່ງນີ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vrqlfaQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--bqIqLoUF--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/f3wvlo4c3gqf3mve1g0n.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vrqlfaQL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--bqIqLoUF--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/f3wvlo4c3gqf3mve1g0n.gif" alt="call local scope from global" width="720" height="405"&gt;&lt;/a&gt;&lt;br&gt;
ຜົນທີ່ໄດ້ຄືມັນຈະທຳການໂຍນ &lt;code&gt;ReferenceError&lt;/code&gt; ສູດດັ້ງເດີມເຈົ້າເກົ່າມາໃສ່ໜ້າເຮົາ, ສາເຫດກໍ່ຍ້ອນມັນບໍ່ເຫັນຕົວປ່ຽນ &lt;code&gt;city&lt;/code&gt; ໃນ global scope, ອີກຢ່າງກໍ່ຄືເຮົາເອີນຈາກ global scope ຢູ່ແລ້ວມັນເລີຍບໍ່ມີ scope ຊັ້ນລຸ່ມໃຫ້ຫາອີກ ແລະ ມັນບໍ່ສາມາດຂຶ້ນໄປຊັ້ນເທິງຂອງ scope ໄດ້ນັ້ນເອງ.&lt;br&gt;
ດ້ວຍວິທີນີ້ເຮົາສາມາດ protect ຕົວປ່ຽນຂອງເຮົາ ແລະ ສາມາດ re-use ຊື່ຕົວປ່ຽນຄືນໄດ້ອີກ.&lt;/p&gt;



&lt;p&gt;ນອກຈາກ global scope ແລະ local scope ແລ້ວມັນຍັງມີ &lt;strong&gt;block scope&lt;/strong&gt; ອີກ🤯. ຕົວປ່ຽນທີ່ປະກາດດ້ວຍ &lt;code&gt;let&lt;/code&gt; ແລະ &lt;code&gt;const&lt;/code&gt; keyword ຈະເປັນຕົວປ່ຽນທີ່ມີ scope ຢູ່ໃນ brackets (&lt;code&gt;{}&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;checkAge&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="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;21&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You cannot drink!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;message&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You can drink!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;message&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;ຖ້າເຮົາລອງ visualize scope ອອກມາກໍ່ຈະໄດ້:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BVbhJ8xX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--t-azbfm3--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/75n1vpm7z4d8924cnvje.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BVbhJ8xX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--t-azbfm3--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880/https://thepracticaldev.s3.amazonaws.com/i/75n1vpm7z4d8924cnvje.png" alt="block scope" width="880" height="496"&gt;&lt;/a&gt;&lt;br&gt;
ເຮົາມີ global scope, function scope ແລະ block scopes 2 ອັນ. ເຊິ່ງເຮົາສາມາດປະກາດຕົວປ່ຽນ &lt;code&gt;message&lt;/code&gt; ໄດ້ 2 ຄັ້ງ, ເນື່ອງຈາກຕົວປ່ຽນຖືກກຳນົດ scope ໄວ້ໃນຂອບເຂດຂອງ brackets.&lt;/p&gt;




&lt;p&gt;ສະຫຼຸບ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ເຮົາຈະເຫັນວ່າ scope chain ເປັນ chain ຂອງການອ້າງອີງເຖິງ value ທີ່ເຮົາສາມາດ access ໄດ້ໃນ context ທີ່ເຮົາກຳລັງເຮັດຢູ່.&lt;/li&gt;
&lt;li&gt;scope ເຮັດໃຫ້ເຮົາສາມາດ re-use ຊື່ຂອງຕົວປ່ຽນທີ່ໄດ້ຖືກປະກາດໄວ້ຢູ່ໃນ scope chain, ເນື່ອງຈາກມັນສາມາດເຮັດວຽກແບບລົງຊັ້ນລຸ່ມໄດ້ຢ່າງດດຽວ ແລະ ບໍ່ສາມາດຂຶ້ນໄປຊັ້ນເທິງຂອງ scope ໄດ້.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ອ້າງອີງ:&lt;br&gt;
&lt;a href="https://dev.to/lydiahallie/javascript-visualized-scope-chain-13pd"&gt;⚡️⛓JavaScript Visualized: Scope (Chain)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JavaScript EP2: Hoisting🫵🏻</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Sat, 01 Apr 2023 10:55:07 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep2-hoisting-jc1</link>
      <guid>https://dev.to/phatsss/javascript-ep2-hoisting-jc1</guid>
      <description>&lt;p&gt;Hoisting - JS Developer ຫຼາຍຄົນກໍ່ຄົງຄຸ້ນຫູກັບຄຳນີ້ຢູ່ບໍ່ໜ້ອຍເນື່ອງຈາກຫຼາຍໆເທື່ອທີ່ໄປຄົ້ນວິທີແກ້ error ຢູ່ google ມັກຈະເຫັນຄົນມາບອກວ່າ error ນີ້ເກີດຈາກ hoisting, ແຕ່ hoisting ມັນແມ່ນແບ້ຫຍັງລ່ະ? ດຽວບົດຄວາມນີ້ຈະມາອະທິບາຍວ່າແບ້ອີ່ຫຍັງຄື hoisting.&lt;/p&gt;

&lt;p&gt;ຕອນທີ່ເລີ່ມຂຽນ JavaScript ຊ່ວງແລກໆກໍ່ເຄີຍພໍ້ເຫດການທີ່ວ່າ variable ບາງໂຕມັນ &lt;code&gt;undefined&lt;/code&gt; ແບບງົງໆ, ຖືກໂຍນ &lt;code&gt;ReferenceErrors&lt;/code&gt; ໃສ່ໜ້າ ແລະ ອີກບັນຫາອື່ນໆ. Hoisting ມັກຖືກຫຼາຍຄົນອະທິບາຍວ່າເປັນການໃສ່ຕົວປ່ຽນ ແລະ function ໄວ້ຢູ່ເທິງສຸດຂອງໄຟລ໌, ແຕ່ວ່າ ມັນແມ່ນແບບນັ້ນແທ້ບໍ່ລ່ະ? ໃຈເຢັນກ່ອນໄບຣ໌ອັນມັນບໍ່ແມ່ນແບບນັ້ນເລີຍ, ມັນບໍ່ແມ່ນສາເຫດຂອງສິ່ງທີ່ເກີດຂຶ້ນ ເຖິງມັນຊິເບິ່ງຄືວ່າມັນໜ້າຈະເປັນແບບນັ້ນກໍ່ຕາມ.&lt;/p&gt;

&lt;p&gt;ເມື່ອ JavaScript Engine ເລີ່ມເຮັດວຽກກັບ script ທີ່ເຮົາຂຽນ ສິ່ງທຳອິດທີ່ມັນເຮັດກໍ່ຄືການຕັ້ງຄ່າ memory ສຳລັບ data ໃນ code ຂອງເຮົາ. ຈະຍັງບໍ່ມີການ execute ໃດໆໃນຂັ້ນຕອນນີ້ເທື່ອ ເວົ້າງ່າຍໆກໍ່ຄືມັນເປັນພຽງການກະກຽມທຸກຢ່າງສຳລັບການ execution. ວິທີການໃນການ store ສ່ວນຂອງ function ແລະ ຕົວປ່ຽນນັ້ນແຕກຕ່າງກັນ, function ຈະຖືກ store ໄວ້ໂດຍອ້າງອີງ function ທັງໝົດ.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xzrkrKZE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--lLfiCbTX--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xzrkrKZE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--lLfiCbTX--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif7.gif" alt="reference to the entire function" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ສ່ວນຂອງຕົວປ່ຽນຈະມີຈຸດທີ່ແຕກຕ່າງຢູ່ໜ້ອຍໜຶ່ງຄື: ໃນ ES6+ ຈະມີການປະກາດຕົວປ່ຽນແບບ &lt;code&gt;let&lt;/code&gt; ແລະ &lt;code&gt;const&lt;/code&gt;. ຕົວປ່ຽນທີ່ປະກາດດ້ວຍ &lt;code&gt;let&lt;/code&gt; ແລະ &lt;code&gt;const&lt;/code&gt; keyword ຈະຖືກ store ແບບ &lt;code&gt;uninitialized&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dBhO_iVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--vRtKMspn--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dBhO_iVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--vRtKMspn--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif8.gif" alt="let and const" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ຕົວປ່ຽນທີ່ປະກາດດ້ວຍ &lt;code&gt;var&lt;/code&gt; keyword ຈະຖືກ store ດ້ວຍຄ່າ default ຄື &lt;code&gt;undefined&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2sHOgdiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--zvlaEaAo--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2sHOgdiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--zvlaEaAo--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif9.gif" alt="var" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເມື່ອຂັ້ນຕອນຕ່າງໆທີ່ກ່າວມາສຳເລັດແລ້ວ ເຮົາຈຶ່ງຈະສາມາດ execute code ໄດ້. ມາເບິ່ງນຳກັນວ່າຖ້າເຮົາໃຊ້ &lt;code&gt;console.log()&lt;/code&gt; 3 ອັນຢູ່ເທິງສຸດຂອງໄຟລ໌ກ່ອນທີ່ເຮົາຈະປະກາດຟັງຊັ່ນ ແລະ ຕົວປ່ຽນ. ເວົ້າງ່າຍກໍ່ຄືເອີ້ນໃຊ້ກ່ອນທີ່ຈະປະກາດ&lt;br&gt;
ເນື່ອງຈາກ function ຖືກ store ໄວ້ໂດຍການອ້າງອີງເຖິງ code ທັງໝົດ, ດັ່ງນັ້ນເຮົາຈະເຫັນວ່າເຮົາສາມາດເອີ້ນໃຊ້ function ກ່ອນທີ່ເຮົາຈະປະກາດ function.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--htX5d0uf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--nk1taOke--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif16.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--htX5d0uf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--nk1taOke--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif16.gif" alt="execution phase" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເມື່ອເຮົາອ້າງເຖິງຕົວປ່ຽນທີ່ປະກາດດ້ວຍ &lt;code&gt;var&lt;/code&gt; keyword ແລ້ວທຳການເອີ້ນໃຊ້ກ່ອນທີ່ຈະປະກາດຕົວປ່ຽນ, ແນ່ນອນວ່າມັນຈະໂຍນຄ່າ default ມາໃຫ້ນັ້ນກໍ່ຄື: &lt;code&gt;undefined&lt;/code&gt;, ແຕ່ບາງເທື່ອມັນກໍ່ຈະເປັນ &lt;code&gt;unexpected&lt;/code&gt;. ໃນຫຼາຍໆກໍລະນີຖ້າພົບເຫດການແບບນີ້ແມ່ນໃຫ້ສັນນິຖານໄວ້ກ່ອນເລີຍວ່າ: ເຮົາອາດຈະລືມປະກາດຕົວປ່ຽນກ່ອນການເອີ້ນໃຊ້ຫຼືບໍ່?&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVY3BfbQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--2nai6XPr--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif17.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVY3BfbQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--2nai6XPr--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif17.gif" alt="invoked var before declare" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເພື່ອປ້ອງກັນບໍ່ໃຫ້ສາມາດອ້າງອີງຕົວປ່ຽນທີ່ເປັນ &lt;code&gt;undefined&lt;/code&gt; ເຊັ່ນດຽວກັບການເອີ້ນໃຊ້ &lt;code&gt;var&lt;/code&gt; keyword ທີ່ເຮົາເຫັນໃນຕົວຢ່າງ. ຈະມີ &lt;code&gt;ReferenceError&lt;/code&gt; ຖືກໂຍນອອກມາເມື່ອໃດກໍ່ຕາມທີ່ເຮົາພະຍາຍາມເອີ້ນໃຊ້ຕົວປ່ຽນທີ່ເປັນ &lt;code&gt;uninitialized&lt;/code&gt;. zone ທີ່ເຮົາເອີ້ນໃຊ້ຕົວປ່ຽນກ່ອນການປະກາດຈະເອີ້ນວ່າ: temporal dead zone - ເຮົາບໍ່ສາມາດອ້າງອີງ ຫຼື ເອີ້ນໃຊ້ຕົວປ່ຽນກ່ອນການ &lt;code&gt;initialization&lt;/code&gt; ໄດ້(ລວມໄປເຖິງ classes ນຳ)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C9yBHWoI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--VVPlWhGC--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif18.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C9yBHWoI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--VVPlWhGC--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif18.gif" alt="ReferenceError" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ເມື່ອ JavaScript Engine ເຮັດວຽກຮອດແຖວທີ່ເຮົາປະກາດຕົວປ່ຽນໄວ້, ມັນຈະທຳການຂຽນທັບ value ທີ່ຢູ່ໃນ memory ທີ່ເປັນ value ທີ່ເຮົາຂຽນໄວ້ໃນ code.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ju2m6AHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--LGEaCMkS--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif12.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ju2m6AHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--LGEaCMkS--/c_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880/https://devtolydiahallie.s3-us-west-1.amazonaws.com/gif12.gif" alt="overwritten" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ສະຫຼຸບ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;function&lt;/code&gt; ແລະ &lt;code&gt;variables&lt;/code&gt; ຈະຖືກ store ໄວ້ໃນ memory ສຳລັບການ execution ກ່ອນທີ່ຈະທຳການ execute code ຂອງເຮົາ, ຂະບວນການທີ່ວ່າມາເອີ້ນວ່າ hoisting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;function&lt;/code&gt; ຈະຖືກ store ໂດຍອ້າງອີງເຖິງ &lt;code&gt;function&lt;/code&gt; ທັງໝົດ, ສ່ວນຕົວປ່ຽນທີ່ໃຊ້ &lt;code&gt;var&lt;/code&gt; keyword ຈະຖືກ store ດ້ວຍຄ່າ default ຄື:​ &lt;code&gt;undefined&lt;/code&gt; ແລະ ຕົວປ່ຽນທີ່ໃຊ້ &lt;code&gt;let&lt;/code&gt; ແລະ &lt;code&gt;const&lt;/code&gt; keyword ແມ່ນຈະຖືກ store ດ້ວຍ &lt;code&gt;uninitialized&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;ອ້າງອີງ: &lt;a href="https://dev.to/lydiahallie/javascript-visualized-hoisting-478h"&gt;🔥🕺🏼 JavaScript Visualized: Hoisting&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>JavaScript EP1: Event Loop♻️</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Thu, 30 Mar 2023 17:49:30 +0000</pubDate>
      <link>https://dev.to/phatsss/javascript-ep1-event-loop-2mop</link>
      <guid>https://dev.to/phatsss/javascript-ep1-event-loop-2mop</guid>
      <description>&lt;p&gt;ຫ່າງຫາຍໄປດົນສົມຄວນ, ດຽວມື້ນີ້ຈະຂຽນເລື່ອງເບື້ອງເລິກເບື້ອງຫຼັງຂອງພາສາ JavaScript ໃຫ້ອ່ານເພື່ອເປັນພື້ນຖານໃນການນຳໃຊ້ພາສາ JavaScript ໃຫ້ມີປະສິດທິພາບ(ຫຼືບໍ່?).&lt;/p&gt;

&lt;h2&gt;
  
  
  Hey JS ♻️!
&lt;/h2&gt;

&lt;p&gt;JS ເປັນພາສາທີ່ເຮັດວຽກແບບ &lt;strong&gt;single-threaded&lt;/strong&gt; ແລະ &lt;strong&gt;non-blocking&lt;/strong&gt; ໝາຍຄວາມວ່າມັນຈະເຮັດວຽກພຽງແຕ່ 1 task ຕໍ່ຄັ້ງ, ເບິ່ງຄືວ່າມັນກໍ່ບໍ່ມີບັນຫາຫຍັງ ແຕ່ລອງຄິດພາບເບິ່ງວ່າເຮົາມີ task ທີ່ຕ້ອງ process ໂດຍໃຊ້ເວລາທັງໝົດ 30 ວິນາທີ. ໃນຂະນະທີ່ task ຍັງເຮັດວຽກບໍ່ແລ້ວເທື່ອ, ແຕ່ເຮົາຕ້ອງມານັ່ງຖ້າ 30 ວິນາທີກ່ອນທີ່ຈະເກີດເຫດການອື່ນໆຕໍ່(JS ຈະ run ຢູ່ເທິງ main thread ຂອງ browser by default ຢູ່ແລ້ວ, ດັ່ງນັ້ນ UI ທຸກຢ່າງຈະຍັງຄ້າງຢູ່ແບບນັ້ນ)😖 ແລ້ວໃຜຊິມານັ່ງຖ້າເວັບຊ້າໆແບບນັ້ນລ່ະ? ນີ້ມັນ 2023 ແລ້ວໃດ🤣🤣🤣&lt;/p&gt;

&lt;p&gt;ໂຊກດີແນ່ທີ່ browser ມີບາງ features ທີ່ JavaScript engine ບໍ່ມີມາໃຫ້ເຊັ່ນ: Web API - ໃນນີ້ປະກອບມີ DOM API, setTimeout, HTTP requests ເປັນຕົ້ນ, ເຊິ່ງມັນເຮັດໃຫ້ເຮົາສາມາດຂຽນແບບ async, non-blocking ໄດ້.&lt;/p&gt;

&lt;p&gt;ເມື່ອເຮົາເອີ້ນໃຊ້ function ໃດໆກໍ່ຕາມ, ສິ່ງທຳອິດທີ່ມັນເຮັດກໍ່ຄືມັນຈະ added ເຂົ້າໄປໃນ &lt;code&gt;call stack&lt;/code&gt;. &lt;code&gt;call stack&lt;/code&gt; ເປັນສ່ວນໜຶ່ງຂອງ JS engine ແລະ ມັນບໍ່ໄດ້ເປັນສິ່ງທີ່ມີສະເພາະ browser - ໝາຍຄວາມວ່າມັນເປັນ stack ລັກສະນະການເຮັດວຽກຂອງມັນກໍ່ຈະເປັນແບບ first in, last out (ຄິດພາບຈານໃສ່ເຂົ້າທີ່ກອງກັນເປັນຊັ້ນໆ ເມື່ອເຮົາຈະໃຊ້ຈານເຫຼົ່ານັ້ນແມ່ນເຮົາຈະທຳການຢິບເອົາຈາກອັນທີ່ຢູ່ເທິງສຸດກ່ອນ)🥞 ແລະ ເມື່ອ function ທີ່ເຮົາເອີ້ນໃຊ້ທຳການ return value ຫຼື ເຮັດວຽກສຳເລັດແລ້ວ ມັນຈະຖືກ popped ອອກໄປຈາກ stack.&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--44yasyNX--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgid1.6.gif" 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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--44yasyNX--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgid1.6.gif" alt="call stack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function ທີ່ຖືກເອີ້ນໃຊ້ຈະຖືກ pushed ເຂົ້າໄປໃນ &lt;code&gt;call stack&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;ເຮັດວຽກບາງຢ່າງພາຍໃນ function ແລ້ວ return value.&lt;/li&gt;
&lt;li&gt;ຫຼັງຈາກເຮັດວຽກສຳເລັດ function ນັ້ນຈະຖືກ popped ອອກໄປຈາກ stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ຈາກຕົວຢ່າງເຫັນວ່າ &lt;code&gt;respond&lt;/code&gt; function ມີການ return &lt;code&gt;setTimeout&lt;/code&gt; function. ເຊິ່ງ &lt;code&gt;setTimeout&lt;/code&gt; ແມ່ນໄດ້ມາຈາກ Web API - ໃຊ້ໃນການ delay task ໂດຍທີ່ບໍ່ມີການ block main thread. callback function ທີ່ເຮົາ passed ໄປຍັງ &lt;code&gt;setTimeout&lt;/code&gt; function, ຈະຢູ່ໃນຮູບແບບ arrow function &lt;code&gt;() =&amp;gt; { return 'Hey'}&lt;/code&gt; ຈະຖືກ added ໄປຍັງ Web API. ໃນຂະນະດຽວກັນ &lt;code&gt;setTimeout&lt;/code&gt; function ແລະ respond function ຈະຖືກ popped ອອກຈາກ stack ແລະ ທັງ 2​ function ຈະ return value ຂອງຕົວເອງ.&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--d_n4m4HH--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif2.1.gif" 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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--d_n4m4HH--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif2.1.gif" alt="setTimeout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ໃນສ່ວນຂອງ Web API ຈະມີຕົວຈັບເວລາ(timer)ຈະຣັນໄປເລື້ອຍໆຈົນກວ່າຈະຄົບ 1000ms ແລ້ວຈຶ່ງຈະເຮັດສ່ວນຂອງ argument ທີ 2 ທີ່ເຮົາ passed ເຂົ້າໄປ. &lt;code&gt;callback function&lt;/code&gt; ຈະຍັງບໍ່ຖືກ added ເຂົ້າໄປໃນ &lt;code&gt;call stack&lt;/code&gt; ເທື່ອ, ແຕ່ຈະ passed ເຂົ້າໄປໃນ &lt;code&gt;queue&lt;/code&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--MewGMdte--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif3.1.gif" 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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--MewGMdte--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif3.1.gif" alt="queue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ໃນສ່ວນນີ້ອາດຈະສັບສົນໜ້ອຍໜຶ່ງ, ຈາກຕົວຢ່າງໝາຍຄວາມວ່າ: ຫຼັງຈາກທີ່ timer ເຮັດວຽກໄປຈົນຄົບ 1000ms &lt;code&gt;callback function&lt;/code&gt; ຂອງເຮົາຈະຖືກ added ເຂົ້າໄປໃນ &lt;code&gt;queue&lt;/code&gt; ກ່ອນເພື່ອລໍຖ້າໃນການທີ່ຈະຖືກ added ເຂົ້າໄປໃນ &lt;code&gt;call stack&lt;/code&gt; ອີກເທື່ອໜຶ່ງ 😵‍💫.&lt;/p&gt;

&lt;p&gt;ແລະພະເອກຂອງເຮົາໃນ ep ນີ້ກໍ່ຄື: &lt;code&gt;event loop&lt;/code&gt; ນີ້ເອງງງງ😎 - ອັນທີ່ຈິງ &lt;code&gt;event loop&lt;/code&gt; ມີໜ້າທີພຽງແຕ່ connecting &lt;code&gt;queue&lt;/code&gt; ກັບ &lt;code&gt;call stack&lt;/code&gt; ຖ້າ &lt;code&gt;call stack&lt;/code&gt; ວ່າງຢູ່(empty)ເທົ່ານັ້ນ🤣🤣🤣. ດັ່ງນັ້ນ ຖ້າຫາກທຸກໆ function ທີ່ຖືກເອີ້ນໃຊ້(invoked)ໄດ້ return value ຂອງຕົວເອງ ແລະ ຖືກ popped ອອກຈາກ &lt;code&gt;call stack&lt;/code&gt; ແລ້ວ, item ທຳອິດທີ່ຢູ່ໃນ &lt;code&gt;queue&lt;/code&gt; ຈະຖືກ added ເຂົ້າມາໃນ &lt;code&gt;call stack&lt;/code&gt;. ໃນກໍລະນີນີ້ບໍ່ມີ function ອື່ນທີ່ຖືກເອີ້ນໃຊ້, ດັ່ງນັ້ນມັນຈຶ່ງຢິບເອົາ item ທຳອິດທີ່ຢູ່ໃນ &lt;code&gt;queue&lt;/code&gt;(ໃນນີ້ມີພຽງ 1 item)ແລ້ວ added ເຂົ້າໃນ &lt;code&gt;call stack&lt;/code&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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--b2BtLfdz--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif4.gif" 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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--b2BtLfdz--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif4.gif" alt="event loop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ຂະບວນການໂດຍຫຍໍ້: callback ໄດ້ຖືກ added ເຂົ້າໄປໃນ &lt;code&gt;call stack&lt;/code&gt;, ເອີ້ນໃຊ້(invoked0, return value, popped callback ອອກຈາກ &lt;code&gt;call stack&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--NYOknEYi--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif5.gif" 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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--NYOknEYi--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif5.gif" alt="callback in call stack"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;ຫຼັງຈາກທີ່ອ່ານຂະບວນການການເຮັດວຽກຂອງ JS ດ້ານເທິງແລ້ວ ເຮົາມາລອງເຝິກສະໝອງດ້ວຍການລອງຄິດພາບການເຮັດວຽກຂອງຂະບວນການດ້ານລຸ່ມເບິ່ງວ່າ 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First&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;bar&lt;/span&gt; &lt;span class="o"&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="nf"&gt;setTimeout&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Second&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;500&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;baz&lt;/span&gt; &lt;span class="o"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Third&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ຈາກ code ດ້ານເທິງຈະມີຂະບວນການດັ່ງນີ້:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--BLtCLQcd--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif14.1.gif" 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%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--BLtCLQcd--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_66%252Cw_880%2Fhttps%3A%2F%2Fdevtolydiahallie.s3-us-west-1.amazonaws.com%2Fgif14.1.gif" alt="event loop test"&gt;&lt;/a&gt;&lt;br&gt;
ອະທິບາຍ:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ເຮົາເອີ້ນໃຊ້(invoked) &lt;code&gt;bar&lt;/code&gt; function, &lt;code&gt;bar&lt;/code&gt; ຈະ return &lt;code&gt;setTimeout&lt;/code&gt; function.&lt;/li&gt;
&lt;li&gt;callback ທີ່ເຮົາ passed ເຂົ້າໄປໃນ &lt;code&gt;setTimeout&lt;/code&gt; ຈະຖືກ added ເຂົ້າໄປໃນ Web API, ເຊິ່ງ &lt;code&gt;setTimeout&lt;/code&gt; function ແລະ &lt;code&gt;bar&lt;/code&gt; ຈະຖືກ popped ອອກຈາກ &lt;code&gt;call stack&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;timer ຈະຣັນໄປເລື້ອຍໆ, ໃນຂະນະດຽວກັນ &lt;code&gt;foo&lt;/code&gt; function ກໍ່ຖືກເອີ້ນໃຊ້ ແລະ logs ຄ່າອອກມາ &lt;code&gt;First&lt;/code&gt;. &lt;code&gt;foo&lt;/code&gt; return (undefined), baz ຖືກເອີ້ນໃຊ້ ແລະ callback ກໍ່ຖືກ added ເຂົ້າໄປໃນ &lt;code&gt;queue&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;baz&lt;/code&gt; ຈະ logs ຄ່າ &lt;code&gt;Third&lt;/code&gt;. &lt;code&gt;event loop&lt;/code&gt; ເຫັນວ່າ &lt;code&gt;call stack&lt;/code&gt; ວ່າງຢູ່(empty) ຫຼັງຈາກທີ່ &lt;code&gt;baz&lt;/code&gt; ໄດ້ທຳການ return ຄ່າສຳເລັດ. ຫຼັງຈາກທີ່ແຕ່ລະ callback ຖືກ added ເຂົ້າໄປໃນ &lt;code&gt;call stack&lt;/code&gt; ແລ້ວ.&lt;/li&gt;
&lt;li&gt;callback ຈະ logs ຄ່າ &lt;code&gt;Second&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;ບ່ອນອ້າງອີງ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif"&gt;✨♻️ JavaScript Visualized: Event Loop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>ສິ່ງທີ່ຄວນຮູ້ກ່ອນທີ່ຈະເປັນ web 3 developer</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Wed, 15 Mar 2023 08:46:15 +0000</pubDate>
      <link>https://dev.to/phatsss/singthiikhwnuuknthiichaepn-web-3-developer-e2e</link>
      <guid>https://dev.to/phatsss/singthiikhwnuuknthiichaepn-web-3-developer-e2e</guid>
      <description>&lt;p&gt;ເຊື່ອວ່າຄົນທີ່ເຂົ້າມາອ່ານບົດຄວາມນີ້ຕ້ອງເຄີຍໄດ້ຍິນຄຳວ່າ web 3.0 ມາແລ້ວທຸກຄົນ,​ ແຕ່ເຄີຍສົງໄສບໍ່ວ່າ web 3.0 ໃນເນື້ອຫາສາລະ ແລະ ຄຸນສົມບັດຂອງມັນຄອບຄຸມຮອດໄສແນ່?, ຄວາມສາມາດຂອງ web 3.0 ຕ່າງຈາກ web 2.0 ຫຼື web 1.0 ແນວໃດ?, ວິທີການພັດທະນາ web 3.0 ເຮັດແນວໃດ? ຫຼື ລວມໄປເຖິງການທີ່ຈະກ້າວໄປເປັນ web 3 developer ຕ້ອງຮູ້ຫຍັງ ແລະ ຮຽນຫຍັງແນ່?. ເຊິ່ງໃນບົດຄວາມຊຸດນີ້ເຮົາຈະຄ່ອຍໆແກະລາຍລະອຽດຂອງ web3 ອອກມາເບິ່ງນຳກັນ, ຖ້າພ້ອມແລ້ວໄປກັນເລີຍ🧑🏻‍💻🧑🏻‍💻🧑🏻‍💻&lt;/p&gt;

&lt;h2&gt;
  
  
  web 3.0 ແມ່ນຫຍັງ? - ແນວຄິດພື້ນຖານ
&lt;/h2&gt;

&lt;p&gt;ໂດຍພຶ້ນຖານແລ້ວ, web 3.0 ຖືວ່າເປັນ big deal ສຳລັບທຸກໆຄົນເລີຍແຫຼະ ເນື່ອງຈາກວ່າມັນມີສັກກະຍະພາບພຽງພໍໃນການປ່ຽນແປງໂລກທັງໃບເລີຍກໍ່ວ່າໄດ້(ໂມ້ບໍ່ວ່ະ 5555). ຖ້າເຮົາສັງເກດເບິ່ງເທຣນຊ່ວງຫຼັງໆນີ້ຮູ້ສຶກວ່າມີຂ່າວກ່ຽວກັບເລື່ອງຂອງ web3(web 3.0) ຢູ່ຫຼາຍສົມຄວນ, ຫຼາຍໆແຫຼ່ງຂ່າວກໍ່ບອກວ່າມັນເປັນແນວຄິດແຫ່ງອານາຄົດພຸ້ນລ່ະ(ມັນຄືເປັນຕາສຶກສາແທ້ລ່ະ) ຖ້າເຮົາເລີ່ມສຶກສາຕັ້ງແຕ່ມື້ນີ້ຖາມວ່າຕົກເທຣນບໍ່? ຖ້າເຮົາເບິ່ງຕາມເທຣນຂອງທົ່ວໂລກບອກໄດ້ເລີຍວ່າກຳລັງເໝາະ(ແຕ່ໜ້າວຽກຢູ່ບ້ານເຮົາກໍ່ຕ້ອງເບິ່ງຕົວຈິງອີກຕື່ມ - ສຶກສາໄວ້ກໍ່ບໍ່ເສຍຫາຍ). ຫຼາຍຄົນກໍ່ສຶກສາໄປຈົນຮອດສາມາດສ້າງ blockchain project ເປັນຂອງຕົວເອງແລ້ວສາມາດປ່ຽນຕຳແໜ່ງວຽກ ແລະ ເພີ່ມຜົນຕອບແທນຂອງຕົວເອງໄດ້ຫຼາຍເລີຍ(ແຕ່ບໍ່ແມ່ນຜູ້ຂຽນເດີ ຮະຮະຮ່າາາ).&lt;/p&gt;

&lt;p&gt;ໃນ web 2.0 ຂໍ້ມູນທຸກຢ່າງແມ່ນຖືກຈັດເກັບຢູ່ສູນກາງ ແລະ ຂໍ້ມູນເຫຼົ່ານັ້ນກໍ່ຖືກຄວບຄຸມໂດຍບັນດາບໍລິສັດ big tech ທັງຫຼາຍທີ່ໃຫ້ບໍລິການໃນການແລກປ່ຽນຂໍ້ມູນສ່ວນບຸກຄົນ(ຂໍ້ມູນຂອງຜູ້ໃຊ້). ສ່ວນຢູ່ໃນ decentralized web(web ທີ່ໄຮ້ສູນກາງ)ຈະບໍ່ຂຶ້ນກັບບຸກຄົນໃດໜຶ່ງ, ບໍລິສັດ/ອົງກອນຕ່າງໆສາມາດແປຮູບ data ຫຼື information ກ່ຽວກັບໃຜ ຫຼື ສິ່ງໃດໆກໍ່ໄດ້ ແລະ ຂໍ້ມູນທຸກຢ່າງຈະເປັນ public ໝາຍຄວາມວ່າຈະບໍ່ມີບຸກຄົນໃດໜຶ່ງມີສິດຄວບຄຸມຂໍ້ມູນທັງໝົດ ທຸກຄົນສາມາດນຳໃຊ້ຂໍ້ມູນຕ່າງໆທີ່ຢູ່ເທິງໄດ້. web3 ກໍ່ສາມາດເວົ້າໄດ້ວ່າມັນເປັນ decentralized web ໄດ້ເຊັ່ນກັນ, ມັນເປັນເຟດ(phase)ທີ 3 ຂອງ internet ແລະ ມັນຖືກສ້າງຂຶ້ນມາບົນພື້ນຖານຂອງ peer-to-peer network ຂອງເຄືອຂ່າຍຄອມພິວເຕີທີ່ແຕ່ລະເຄື່ອງຈະບໍ່ມີເຄື່ອງໃດທີ່ເປັນຕົວກາງ.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ໃນນິຍາມຂອງ web3 ແມ່ນມັນຈະມີອີກຫຼາຍຄຸນສົມບັດ, ແຕ່ສະຫຼຸບໃຫ້ສັ້ນທີ່ສຸດເພື່ອໃຫ້ເຂົ້າໃຈງ່າຍຂຶ້ນ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ຢາກເປັນ web3 developer ຕ້ອງມີສະກິວຫຍັງແດ່?
&lt;/h2&gt;

&lt;p&gt;ການທີ່ເຮົາຈະອັບສະກິວໂຕເອງໄປເປັນ web3 developer ເຕັມຕົວມັນກໍ່ອາດຈະໃຊ້ເວລາພໍສົມຄວນ, ແຕ່ຖ້າເຮົາມີການວາງແຜນຢ່າງຈິງຈັງໃນການສຶກສາ ຜູ້ຂຽນເຊື່ອວ່າທຸກຄົນສາມາດເປັນ web3 developer ໄດ້. ເຮົາມາເບິ່ງກັນວ່າບັນດາ skills ຕ່າງໆທີ່ເຮົາຄວນສຶກສາມີຫຍັງແດ່? ອ່ານຕໍ່ດ້ານລຸ່ມໄດ້ເລີຍ.&lt;/p&gt;

&lt;h3&gt;
  
  
  Web 2.0 skills
&lt;/h3&gt;

&lt;p&gt;ຢ່າຟ້າວຫ້າວໃສ່ web3 ຖ້າການເປັນ web2 developer ຍັງບໍ່ແຂງແຮງເທື່ອ, ເລື່ອງນີ້ມັນບໍ່ຕະລົກເລີຍຖ້າຫາກຄວາມຮູ້ພື້ນຖານດ້ານ web2 ຂອງເຮົາຍັງບໍ່ແໜ້ນພໍ ແລ້ວເຮົາພັດຢາກຈະຂ້າມຂັ້ນໄປເລີ່ມສຶກສາພວກ web3 stack ເລີຍ ການເຮັດແບບນີ້ຂ້ອນຂ້າງມີຄວາມສ່ຽງຫຼາຍດ້ານ, ເຊິ່ງມັນອາດຈະສົ່ງຜົນຕໍ່ການພັດທະນາຂອງເຮົາ ແລະ ລວມໄປເຖິງບັນດາ code ທີ່ເຮົາຂຽນອີກ. ສະນັ້ນ ການທີ່ຈະກ້າວໄປຫາ web3 ຄວນເຂົ້າໃຈຂະບວນການພັດທະນາ web2 ໃຫ້ເລິກພໍສົມຄວນ - ຖ້າຖາມວ່າໄປສຶກສາ web3 ເລີຍຜິດບໍ່? ຫຼື ລົງມີຂຽນ smart contact ເຮັດ blockchain project ຜິດບໍ່? ຄຳຕອບມັນກໍ່ບໍ່ຜິດດອກຖ້າຫາກເຮັດອອກມາແລ້ວມັນດີ ແລະ ຄຳວ່າດີໃນທີ່ນີ້ຄືຕ້ອງວັດຜົນໄດ້ໃນດ້ານຕ່າງໆອີກເຊັ່ນ:​ ຄວາມປອດໄພ, ປະສົບການການໃຊ້ງານຂອງ users, performance ຂອງ app, ແຜນໃນການ scale app ແລະ ຍັງອີກຫຼາຍໆຂໍ້ທີ່ເຮົາຕ້ອງໄດ້ຄຳນຶງເຖິງກ່ອນການພັດທະນາ.&lt;/p&gt;

&lt;p&gt;ໂດຍປົກກະຕິ, ເຮົາຈະບໍ່ສາມາດກາຍເປັນ master web3 ໄດ້ເລີຍຖ້າຫາກບໍ່ມີ background ຈາກ web2 ທີ່ດີພໍຕົວ. ດັ່ງນັ້ນ ກ່ອນເຮົາຈະສຶກສາດຳດິ່ງເລິກລົງສູ່ຫຼຸມຂອງ web3 stack ມັນກໍ່ລ້ວນແລ້ວແຕ່ຕ້ອງມີພື້ນຖານທີ່ດີຈາກ web2 ທັງນັ້ນ.&lt;/p&gt;

&lt;p&gt;ຖ້າເຮົາມີສະກິວພື້ນຖານໃນການພັດທະນາ web2 ເຊັ່ນ: ReactJS, VueJS, AngularJS ຫຼື ອື່ນໆທີ່ກ່ຽວຂ້ອງມັນກໍ່ຈະເປັນຕົວຊ່ວຍຊັ້ນດີໃນການທີ່ຈະອັບສະກິວໄປເປັນ web3 developer ຍ້ອນວ່າບັນດາ decentralized applications ມີ standard ມາຈາກ Vanilla Javascript ຫຼື Javascript Front-end Frameworks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blockchain Fundamentals
&lt;/h3&gt;

&lt;p&gt;ຢາກເປັນ web3 developer ຕ້ອງຮູ້ ແລະ ເຂົ້າໃຈກ່ຽວກັບ Blockchain ຢ່າງຫຼີກລ່ຽງບໍ່ໄດ້, ຖ້າຖາມວ່າຕ້ອງຮູ້ເລິກສ່ຳໃດ? - ກໍ່ຄວນຮູ້ ແລະ ເຂົ້າໃຈໃນລະດັບທີ່ວ່າ:​ ສາມາດອະທິບາຍໄດ້ວ່າ blockchain ແມ່ນຫຍັງ?, ມັນເຮັດວຽກຈັ່ງໃດ?, ເປັນຫຍັງເຮົາຈຶ່ງໃຊ້ມັນ?.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blockchain ແມ່ນຫຍັງ?&lt;/strong&gt;&lt;br&gt;
ໃນທີ່ນີ້ຈະຂໍອະທິບາຍວ່າ blockchain ເປັນ ເຄື່ອຂ່າຍ(network)ຂອງຄອມພິວເຕີທີ່ມີການແບ່ງປັນຂໍ້ມູນ ຫຼື ໃຊ້ຂໍ້ມູນຮ່ວມກັນ ແລະ ເຊື່ອມຕໍ່ກັນໃນລັກສະນະທີ່ການປ່ຽນເປັນຂໍ້ມູນເປັນໄປໄດ້ຍາກ ຫຼື ອາດເວົ້າໄດ້ວ່າມັນແທບຈະເປັນໄປບໍ່ໄດ້ເລີຍທີ່ຈະເຈາະ ຫຼື ໂກງໃນລະບົບ. ມັນເປັນລະບົບທີ່ໄຮ້ສູນກາງ, ມີການກະຈາຍອຳນາດ ແລະ ມີການບັນທຶກທຸກທຸລະກຳທີ່ເກີດຂຶ້ນເອີ້ນວ່າ blocks(ໃຊ້ໃນການບັນທຶກທຸລະກຳທີ່ເກີດຂຶ້ນຢູ່ເທິງເຄືອຂ່າຍຄອມພິວເຕີ).&lt;/p&gt;

&lt;p&gt;ອ່ານມາຮອດດບ່ອນນີ້ເຊື່ອວ່າທຸກຄົນຈະເຂົ້າໃຈກ່ຽວກັບ blockchain technology ໃນບໍລິບົດອື່ນໆນອກເໜືອຈາກເລື່ອງຂອງ cryptocurrencies. ມັນຖືກນຳໃຊ້ໃນອີກຫຼາຍໆດ້ານເຊັ່ນ: decentralized finance(De-Fi), NFTs, Gaming, Metaverse, supply chain tracking ແລະ ອື່ນໆ. ນອກຈາກນີ້ເຮົາກໍ່ຕ້ອງຄົ້ນຄວ້າເບິ່ງອີກຕື່ມວ່າ: blockchain ແມ່ນຫຍັງ?(ໂດຍນິຍາມ), ມັນເຮັດວຽກຈັ່ງໃດ?, ເຮົາຈະນຳໃຊ້ ຫຼື ໂຕ້ຕອບກັບ blockchain ໄດ້ແນວໃດ? ແລະ ວິທີການທີ່ຈະ integrated web applications ກັບ blockchain technology ເຮັດແນວໃດ?.&lt;/p&gt;

&lt;p&gt;ສຳລັບຜູ້ທີ່ກຳລັງມີໄຟ ແລະ ສົນໃຈກ່ຽວກັບ blockchain ກໍ່ອາດຈະເລີ່ມຈາກສຶກສາ Ethereum blockchain ເພາະວ່າມັນເປັນ network ທີ່ນິຍົມຫຼາຍ, ຄົ້ນຫາຂໍ້ມູນຂ້ອນຂ້າງງ່າຍ ມັນຈຶ່ງເປັນປະໂຫຍດຫຼາຍໃນການຊ່ວຍໃຫ້ເຮົາເລີ່ມຕົ້ນສຶກສາໃນເລື່ອງຂອງ blockchain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ຖ້າຍັງຄິດພາບບໍ່ອອກໃຫ້ລອງຄິດວ່າ blockchain ປຽບເໝືອນຖານຂໍ້ມູນທີ່ບັນທືກບັນດາຂໍ້ມູນທຸລະກຳທີ່ເກີດຂຶ້ນຢູ່ເທິງ blockchain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Smart Contracts
&lt;/h3&gt;

&lt;p&gt;smart contracts ເປັນ software(ຊຸດຄຳສັ່ງ)ທີ່ຖືກຈັດເກັບໄວ້ຢູ່ໃນບັນດາ blockchain-based platform, ເຊິ່ງມີຈຸດປະສົງເພື່ອດຳເນີນການ, ຄວບຄຸມ ຫຼື ບັນທຶກເອກະສານຕາມເຫດການ ແລະ actions ທີ່ກ່ຽວຂ້ອງຢ່າງອັດຕະໂນມັດພາຍໃຕ້ເງື່ອນໄຂ ແລະ ຂໍ້ຕົກລົງຕ່າງໆທີ່ກຳນົດໄວ້. ໃນການໃຊ້ smart contracts ເຮົາສາມາດນຳໃຊ້ບັນດາຊຸດຄຳສັ່ງສະເພາະຂອງ blockchain ໃນການດຳເນີນການໄດ້.&lt;/p&gt;

&lt;p&gt;ແລະເຊັ່ນດຽວກັບສິ່ງອື່ນໆທີ່ຣັນຢູ່ເທິງ blockchain, ເຮົາບໍ່ສາມາດແກ້ໄຂ ຫຼື ປ່ຽນແປງ code ຂອງ smart contracts ໄດ້ບໍ່ວ່າຈະກໍລະນີໃດໆກໍ່ຕາມ. ອີງຕາມຂໍ້ກຳນົດຂອງຝັ່ງ technical ທີ່ລະບຸວ່າມັນຕ້ອງ immutability(ບໍ່ສາມາດປ່ຽນແປງໄດ້). Smart contracts ສາມາດນຳໃຊ້ເຮັດໄດ້ຫຼາຍຢ່າງແຕ່ທີ່ເຫັນໃຊ້ກັນຢ່າງແພ່ຫຼາຍກໍ່ຈະມີ: ສ້າງ Cryptocurrency, mint NFTs, ໃຊ້ຈັດການ backend ຂອງ decentralized application ເຫຼົ່ານີ້ເປັນຕົ້ນ.&lt;/p&gt;

&lt;p&gt;ເມື່ອຮູ້ແລ້ວວ່າ smart contracts ມີຄວາມສຳຄັນສ່ຳໃດໃນ blockchain, ຂັ້ນຕອນຕໍ່ໄປກໍ່ຄົງຈະແມ່ນການທີ່ຕ້ອງຮຽນຮູ້ວິທີພັດທະນາມັນແມ່ນບໍ່ລ່ະ?. ສະນັ້ນ ໃນການຂຽນ smart contracts ໃຫ້ໄປຣັນຢູ່ເທິງ blockchain ເຮົາອາດຈະຕ້ອງມີຄວາມຮູ້ເລື່ອງຂອງພາສາໂປຣແກຣມທີ່ຊື່ວ່າ Solidity,​ ແນ່ນອນວ່າມັນບໍ່ໄດ້ມີພຽງພາສາດຽວທີ່ສາມາດໃຊ້ພັດທະນາ ແຕ່ Solidity ຖືວ່າເປັນພາສາທີ່ໄດ້ຮັບຄວາມນິຍົມຫຼາຍ ແລະ ມີຂໍ້ມູນທີ່ຂຽນກ່ຽວກັບການຂຽນພາສານີ້ອອກມາຫຼາຍ, ເຊິ່ງມັນເປັນຜົນດີຕໍ່ກັບຜູ້ທີ່ກຳລັງສຶກສາຢູ່.&lt;/p&gt;

&lt;p&gt;Solidity ເປັນ object-oriented programming language ທີ່ໃຊ້ສຳລັບການຂຽນ smart contracts, ມັນຖືກໃຊ້ໃນການ implement smart contract ເທິງບັນດາ blockchain platform ຕ່າງໆ ແລະ ມັນຍັງເປັນພາສາໃໝ່ທີ່ໃຊ້ໃນ Ethereum blockchain ທີ່ລວມເອົາຂໍ້ດີຈາກຫຼາຍໆພາສາ, ເຊິ່ງຜູ້ທີ່ສ້າງພາສາ Solidity ໄດ້ຮັບແຮງບັນດານໃຈມາຈາກ JavaScript, Java, C++, Rust ແລະ ອີກຫຼາຍໆພາສາ ຈຶ່ງເຮັດໃຫ້ Solidity ມີຄວາມຫຼາກຫຼາຍ ແລະ ໃຊ້ງານງ່າຍ.&lt;/p&gt;

&lt;p&gt;ເມື່ອເຮົາເລີ່ມຂຽນ Solidity ເຮົາຈະສັງເກດເຫັນຄວາມໃກ້ຄຽງກັບພາສາໂປຣແກຣມອື່ນໆ ຕົວຢ່າງດ້ານລຸ່ມ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: UNLICENSED
&lt;/span&gt;&lt;span class="k"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"hardhat/console.sol"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;FirstContract&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hey, This is Spata!!!"&lt;/span&gt;&lt;span class="p"&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;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;memory&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="s"&gt;'I love her, but she got sugar daddy'&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;ອີກຂໍ້ດີຢ່າງໜຶ່ງຂອງການຮຽນພາສາ Solidity ກໍ່ຄືເລື່ອງຂອງຕະຫຼາດແຮງງານດ້ານນີ້(ຕ່າງປະເທດ),​ ຫຼາຍໆບໍລິສັດທີ່ມີໂປຣເຈັກ Blockchain ຂອງຕົວເອງກໍ່ຕ້ອງການນັກພັດທະນາດ້ານນີ້ຫຼາຍຂຶ້ນ.&lt;/p&gt;

&lt;p&gt;ໃນຂະບວນການພັດທະນາ smart contract ຖ້າເຮົາ deploy ໄປແລ້ວແນ່ນອນວ່າມັນບໍ່ສາມາດແກ້ໄຂ code ໄດ້,​ ດັ່ງນັ້ນການພັດທະນາຕ້ອງໄດ້ມີເຄື່ອງມືຫຼາຍໆຢ່າງທີ່ໃຊ້ໃນແຕ່ລະດ້ານເຊັ່ນ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ບັນດາ Solidity Frameworks ອາດຈະເລືອກ Hardhat ຫຼື Truffle.&lt;/li&gt;
&lt;li&gt;ເຄື່ອງມືໃນການທົດສອບ(Testing)ມີ Mocha, Chai ຫຼື Ganache.&lt;/li&gt;
&lt;li&gt;ເຄື່ອງມືໃນການພັດທະນາ(Development)ມີ Infura ຫຼື Alchemy.
*ລືມໄປອີກຢ່າງໜຶ່ງ,​ມີເວັບແອັບທີ່ຊື່ວ່າ Remix IDE ທີ່ໃຊ້ໃນການພັດທະນາ, ການ Deploy ແລະ ການຈັດການກັບ smart contract ສຳລັບ Ethereum blockchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decentralized Applications (dApps)
&lt;/h3&gt;

&lt;p&gt;ຫຼັງຈາກທີ່ເຮົາຂຽນ ແລະ deploy smart contract ຂອງເຮົາສຳເລັດແລ້ວ,​ ເຮົາກໍ່ຄວນມີສ່ວນທີ່ໃຫ້ User ເຂົ້າໄປໃຊ້ງານ ແລະ ບ່ອນນີ້ເອງທີ່ເຮົາຈະໄດ້ໃຊ້ສະກິວ web 2.0 ຂອງເຮົາ. ການທີ່ຈະສ້າງ dApp(ເປັນໄດ້ທັງ web ແລະ app) ຂຶ້ນມາໃຫ້ມະປະສິດທິພາບທີ່ບໍ່ເຮັດໃຫ້ User ນັ່ງງົງໃນ App ຂອງເຮົາ, ເຮົາກໍ່ຕ້ອງຮູ້ຈັກວິທີຂຽນ Web ຫຼື App ທີ່ດີໃນລະດັບໜຶ່ງເລີຍ ແລະ ສິ່ງທີ່ຕ່າງໄປຈາກການຂຽນ web/app ແບບເດີມກໍ່ຈະມີຢູ່ 2 ສ່ວນຫຼັກໆຄື: ເຮັດໃຫ້ web/app ຂອງເຮົາວຽກຮ່ວມກັບ blockchain ແລະ ສ່ວນທີ່ເຮັດວຽກຮ່ວມກັບ wallet. ໃນການທີ່ຈະ integrate blockchain ກັບ web/app ເຮົາຕ້ອງໄດ້ອາໄສ Javascript library ເຊັ່ນ: Web3.js ແລະ Ethers.js ສ່ວນຈະເລືອກໃຊ້ອັນໃດນັ້ນກໍ່ຕ້ອງໄປພິຈາລະນາກັນເອົາເອງ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wallet ແມ່ນຫຍັງ?&lt;/strong&gt;&lt;br&gt;
ເຊື່ອວ່າຫຼາຍຄົນກໍ່ຄົງຈະເຄີຍໃຊ້ wallet ຜ່ານມາແລ້ວ ແລະ ແນ່ນອນວ່າການທີ່ຈະ interact ກັບ blockchain ເຮົາຕ້ອງມີ wallet ຢ່າງໜ້ອຍ 1 wallet. ເຊິ່ງ wallet ຈະຊ່ວຍໃນການແລກປ່ຽນສິນຊັບດິຈິຕອນໄດ້ຢ່າງວ່ອງໄວ ແລະ ແຕ່ລະ transactions ທີ່ເກີດຂຶ້ນຈະມີການເຂົ້າລະຫັດ ເຮັດໃຫ້ມີຄວາມປອດໄພຂ້ອນຂ້າງສູງ. wallet ເຊິ່ງສາມາດເຂົ້າເຖິງໄດ້ຈາກທັງມືຖື ແລະ ເວັບຈະຮັກສາຂໍ້ມູນປະຈຳຕົວ ແລະ ຄວາມເປັນສ່ວນຕົວຂອງຜູ້ໃຊ້,​ ນອກຈາກນີ້ຍັງມີຄຸນສົມບັດທີ່ຈຳເປັນໃນການແລກປ່ຽນ ແລະ ການໂອນລະຫວ່າງແຕ່ລະຝ່າຍທີ່ມີຄວາມປອດໄພ. ຄ້າຍກັບຄວາມສາມາດໃນການສົ່ງ/ຮັບເງິນຂອງ Paypal ຫຼື CashApp ຕ່າງແຕ່ຈະເປັນການສົ່ງ/ຮັບ cryptocurrency ແທນ.&lt;/p&gt;

&lt;p&gt;ຖ້າຈະໃຫ້ນັບ wallet ໃນທ້ອງຕະຫຼາດທຸກມື້ນີ້ຖືວ່າມີຫຼາຍເຈົ້າພໍສົມຄວນ, ສ່ວນຕົວແມ່ນແນະນຳໃຫ້ລອງຮຽນ integrate dApp ຂອງເຮົາກັບ Metamask ກ່ອນ, ເນື່ອງຈາກຄົນໃຊ້ຫຼາຍ ແລະ ຫາຂໍ້ມູນງ່າຍ. ອີກອັນໜຶ່ງທີ່ແນະນຳກໍ່ຈະເປັນ WalletConnect ໂຕນີ້ຈະຊ່ວຍໃຫ້ເຮົາສາມາດ connect ກັບ wallet ອື່ນໆໄດ້.&lt;br&gt;
&lt;strong&gt;ຮຽນນຳໃຊ້ web3.js ຫຼື ethers.js connect ກັບ dApp ຂອງເຮົາ&lt;/strong&gt;&lt;br&gt;
ເປັນຫຍັງຄືແນະນຳແຕ່ 2 ໂຕນີ້ເປັນຫຼັກ, ເຫດຜົນກໍ່ບໍ່ມີຫຍັງຫຼາຍເກີນກວ່າການທີ່ມັນເປັນ Javascript library ທີ່ຍອດຮິດນີ້ລ່ະ ສ່ວນອີກເຫດຜົນກໍ່ຄືເຮົາຫາຂໍ້ມູນກ່ຽວກັບການໃຊ້ງານ 2 lib ນີ້ງ່າຍ.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;web3.js - ເປັນ collection ຂອງ libraries ທີ່ອະນຸຍາດໃຫ້ເຮົາສາມາດ connect ກັບ local ຫຼື remote Ethereum node ຜ່ານ HTTP, WebSocket ແລະ communication protocols ອື່ນໆໂດຍກົງຈາກ JavaScript Based
front-end.&lt;/li&gt;
&lt;li&gt;ethers.js - ເປັນ lightweight javascript library ທີ່ເປັນອີກທາງເລືອກໜຶ່ງນອກຈາກ web3.js ໃນການ build javascript frontend ແລະ interact ກັບ Ethereum blockchain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resource ທີ່ໜ້າສົນໃຈໃນການສຶກສາດ້ານນີ້
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=qOVAbKKSH10"&gt;Blockchain Technology Explained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.web3.university/"&gt;Web3 University&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ibm.com/blogs/blockchain/category/blockchain-development/"&gt;IBM Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.alchemy.com/blog"&gt;Alchemy Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://academy.101blockchains.com/courses/enterprise-blockchains-fundamentals"&gt;Enterprise Blockchains Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cryptozombies.io/"&gt;Cryptozombies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.chainshot.com/courses"&gt;Chainshot Courses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.useweb3.xyz/"&gt;useWeb3.xyz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/c/EatTheBlocks/videos"&gt;EatTheBlocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://buildspace.so/"&gt;Buildspace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learnweb3.io/"&gt;LearnWeb3 dAO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;ເຮົາມີ discord community ນ້ອຍໆທີ່ເຮົາຈະລົມກັນເລື່ອງສັບເພເຫລະກັນຢູ່ໃນນັ້ນ, ຖ້າໃຜສົນໃຈເຂົ້າໄປເຮັດໃຫ້ community ເຮົາຄຶກຄື້ນ ແລະ ອຶກກະທຶກຕຶກໂຄມໄປນຳກັນ ລິ້ງດ້ານລຸ່ມ:&lt;br&gt;
*&lt;/em&gt;&lt;a href="https://discord.gg/4j9vmYFX"&gt;LocalCode&lt;/a&gt;**&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ref: &lt;a href="https://dev.to/abubakardev/the-roadmap-breaking-into-web-30-el3"&gt;The Roadmap: Breaking into Web 3.0&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>blockchain</category>
      <category>programming</category>
      <category>beginners</category>
      <category>web3</category>
    </item>
    <item>
      <title>DESIGN PATTERNS</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Tue, 27 Dec 2022 05:52:25 +0000</pubDate>
      <link>https://dev.to/phatsss/design-patterns-2cig</link>
      <guid>https://dev.to/phatsss/design-patterns-2cig</guid>
      <description>&lt;h2&gt;
  
  
  What's a design pattern?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Design patterns&lt;/strong&gt; ເປັນວິທີແກ້ໄຂບັນຫາທົ່ວໄປທີ່ມັກເກີດໃນຂະບວນການພັດທະນາ software, ເຊິ່ງປຽບເໝືອນພິມຂຽວ(blueprint)ທີ່ສ້າງ ຫຼື ອອກແບບໄວ້ລ່ວງໜ້າເຊິ່ງເຮົາສາມາດປັບແຕ່ງເພື່ອແກ້ໄຂບັນຫາທີ່ເກີດຊ້ຳໆໃນ code ຂອງເຮົາໄດ້.&lt;/p&gt;

&lt;p&gt;ເຮົາບໍ່ສາມາດຄົ້ນຫາ pattern ໃນເນັດ ແລະ copy ມາໃສ່ program ຂອງເຮົາຕົງໆແບບເສກຄາຖາໃສ່ code ໄດ້, ເຊິ່ງມັນບໍ່ຄືກັນກັບການ copy code ຈາກເນັດມາໃສ່ໃນ function ຖ້າເຮັດວຽກໄດ້ແລ້ວຈົບ. pattern ບໍ່ແມ່ນຮູບແບບຂອງ code ສ່ວນໃດສ່ວນໜຶ່ງ ແຕ່ມັນເປັນແນວຄິດໃນການແກ້ໄຂບັນຫາສະເພາະເຈາະຈົງ, ເຊິ່ງເຮົາສາມາດປະຕິບັດຕາມຮູບແບບຂອງແຕ່ລະ pattern ເພື່ອໃຊ້ແກ້ໄຂບັນຫາຕົວຈິງຂອງ program.&lt;/p&gt;

&lt;p&gt;ຫຼາຍຄົນມັກຈະສັບສົນລະຫວ່າງ pattern ແລະ algorithms ເນື່ອງຈາກ concept ທັງສອງແມ່ນອະທິບາຍວິທີການແກ້ໄຂບັນຫາບາງບັນຫາທີ່ຮູ້ແລ້ວ. ໃນຂະນະທີ່ algorithms ຈະກຳນົດວິທີການແກ້ໄຂບັນຫາເພື່ອບັນລຸເປົ້າໝາຍໄດ້ຢ່າງຊັດເຈນ(ມີຮູບແບບໃນການຂຽນ code ຊັດເຈນ), ແຕ່ pattern ເປັນຄຳອະທິບາຍວິທີການແກ້ໄຂບັນຫາໃນລະດັບສູງ, ເຊິ່ງ code ທີ່ນຳໃຊ້ pattern ດຽວກັນແຕ່ຢູ່ຄົນລະ projects, code ສ່ວນນັ້ນກໍ່ອາດຈະຕ່າງກັນ.&lt;/p&gt;

&lt;p&gt;ຖ້າຈະປຽບທຽບ algorithms ກໍ່ຄືສູດການເຮັດອາຫານ:​ເຊິ່ງທັງສອງຈະກຳນົດວິທີການໄວ້ຢ່າງຊັດເຈນເພື່ອໃຫ້ໄດ້ຜົນລັບຕາມເປົ້າໝາຍທີ່ວາງໄວ້. ໃນຂະນະທີ່ pattern ປຽບເໝືອນພິມຂຽວ: ເຊິ່ງເຮົາສາມາດເບິ່ງຜົນລັບ ແລະ ຄຸນລັກສະນະຂອງມັນໄດ້ວ່າເປັນແບບໃດ, ແຕ່ລຳດັບຂອງການໃຊ້ງານແມ່ນຂຶ້ນຢູ່ກັບເຮົາ.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the pattern consist of?
&lt;/h2&gt;

&lt;p&gt;pattern ສ່ວນໃຫຍ່ແມ່ນໄດ້ອະທິບາຍຄຸນລັກສະນະໄວ້ພໍປະມານເພື່ອໃຫ້ຄົນທີ່ເອົາໄປນຳໃຊ້ສາມາດນຳໄປປັບໃຊ້ໃນໄດ້ໃນຫຼາຍບໍລິບົດ. ແຕ່ມັກຈະຖືກອະທິບາຍໃນຮູບແບບຕ່າງໆດັ່ງນີ້:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Intent&lt;/strong&gt;(ເຈດຕະນາ)ຂອງ pattern ຈະອະທິບາຍທັງບັນຫາ ແລະ ແນວທາງແກ້ໄຂບັນຫາ.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Motivation&lt;/strong&gt;(ແຮງຈູງໃຈ)ຈະອະທິບາຍບັນຫາເພີ່ມເຕີມ ແລະ ແນວທາງແກ້ໄຂທີ່ pattern ເຮັດໃຫ້ເປັນໄປໄດ້.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure&lt;/strong&gt;(ໂຄງສ້າງ)ຂອງ classes ສະແດງແຕ່ລະສ່ວນຂອງ pattern ແລະ ຄວາມກ່ຽວຂ້ອງກັນ.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code example&lt;/strong&gt;(ຕົວຢ່າງ Code)ໃນພາສາການຂຽນໂປຣແກຣມຍອດນິຍົມພາສາໜຶ່ງຊ່ວຍໃຫ້ເຂົ້າໃຈແນວຄິດເບື້ອງຫຼັງຂອງ pattern ໄດ້ງ່າຍຂຶ້ນ.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why should I learn patterns?
&lt;/h2&gt;

&lt;p&gt;ໃນຄວາມເປັນຈິງກໍ່ຄືເຈົ້າກໍ່ອາດຈະເປັນໂປຣແກຣມເມີຄົນໜຶ່ງທີ່ເຮັດວຽກມາຫຼາຍປີໂດຍທີ່ຍັງບໍ່ຮູ້ຈັກ pattern ໃດເລີຍ(ຜູ້ຂຽນກໍ່ເປັນໜຶ່ງໃນນັ້ນ) ແລະ ເຊື່ອວ່າຫຼາຍຄົນກໍ່ເປັນຈັ່ງຊັ້ນ ຫຼື ອາດຈະໃຊ້ຢູ່ແລ້ວແຕ່ບໍ່ຮູ້ວ່າໂຕເອງໃຊ້ຢູ່. ແລ້ວເປັນຫຍັງເຮົາຄືບໍ່ລອງສະລະເວລາມາລອງສຶກສາ pattern ແນ່?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Design pattern ເປັນ toolkit ໃນການແກ້ໄຂບັນຫາທີ່ຜ່ານການທົດລອງ ແລະ ທົດສອບສຳລັບບັນຫາທົ່ວໄປໃນການອອກແບບ software ເຖິງແມ່ນວ່າເຮົາຈະບໍ່ເຄີຍພົບບັນຫາເຫຼົ່ານັ້ນມາກ່ອນ ແຕ່ການທີ່ເຮົາໄດ້ສຶກສາ pattern ມັນກໍ່ຍັງມີປະໂຫຍດ, ເພາະມັນສອນວິທີແກ້ໄຂບັນຫາທຸກປະເພດໂດຍໃຊ້ຫຼັກການອອກແບບເຊີງວັດຖຸ(object-oriented design)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design patterns ມີການກຳນົດພາສາທົ່ວໄປທີ່ເຮົາ ແລະ ເພື່ອນຮ່ວມທີມສາມາດໃຊ້ເພື່ອສື່ສານກັນໄດ້ຢ່າງມີປະສິດທິພາບຫຼາຍຂຶ້ນ.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*ໃນຄວາມເປັນຈິງຖ້າຈະເອົາມານຳໃຊ້ເຂົ້າໃນຂະບວນການພັດທະນາກໍ່ຕ້ອງຄຳນຶງເຖິງຫຼາຍໆປັດໄຈ, ບາງຄັ້ງມັນກໍ່ອາດຈະບໍ່ເໝາະ.&lt;/p&gt;

&lt;p&gt;ບົດຄວາມນີ້ສະຫຼຸບຈາກເວັບໄຊ &lt;a href="https://refactoring.guru/" rel="noopener noreferrer"&gt;refactoring.guru&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Naming Things &lt;for developer /&gt;</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Fri, 18 Nov 2022 04:40:57 +0000</pubDate>
      <link>https://dev.to/phatsss/naming-things-3i96</link>
      <guid>https://dev.to/phatsss/naming-things-3i96</guid>
      <description>&lt;p&gt;ໃນຂະບວນການຂອງການພັດທະນາໂປຣເຈັກໃດໜຶ່ງນອກຈາກຈະມີ Architecture ທີ່ດີ ແລະ ທີມທີ່ມີຄຸນນະພາບແລ້ວ(ແລະ ຕ້ອງເທ້ໆແນ່ຈັກໜ້ອຍ) ສິ່ງໜຶ່ງທີ່ລະເລີຍບໍ່ໄດ້ເລີຍກໍ່ຄົງຈະແມ່ນມາດຕະຖານໃນການພັດທະນາ, ເຊິ່ງມາດຕະຖານໃນການພັດທະນາສຳລັບແຕ່ລະທີມ ຫຼື ແຕ່ລະອົງກອນກໍ່ອາດຈະໃຊ້ບໍ່ຄືກັນ, ສິ່ງໜຶ່ງທີ່ຂ້ອນຂ້າງຈະເປັນບັນຫາສຳລັບເຫຼົ່າ developer ຫຼາຍໆຄົນກໍ່ຄົງຈະມີການຕັ້ງຊື່ຕົວປ່ຽນນີ້ລ່ະ ມັນອາດຈະເບິ່ງຄືເປັນບັນຫານ້ອຍໆທີ່ຫຼາຍຄົນເບິ່ງຂ້າມ ແຕ່ມັນກໍ່ສ້າງຄວາມລຳຄານໃຈໃຫ້ຄົນໃນທີມບໍ່ຫຼາຍກໍ່ໜ້ອຍເລີຍແຫຼະ.&lt;/p&gt;

&lt;p&gt;ເມື່ອລອງຊອກຂໍ້ມູນປະມານວ່າ: "ໜ້າວຽກທີ່ຍາກທີ່ສຸດຂອງບັນດານັກພັດທະນາ" ພົບວ່າການຕັ້ງຊື່ອີ່ຫຍັງບາງຢ່າງຈະຕິດໜຶ່ງໃນນັ້ນສະເໝີ(ບາງເທື່ອຂ້ອຍເອງກະໃຊ້ເວລາໃນການຕັ້ງຊື່ຟັງຊັ່ນ ຫຼື ຕົວປ່ຽນດົນກວ່າການຂຽນຟັງຊັ່ນໂດຍລວມອີກ ຮະຮະຮ່າາາາ), ດັ່ງນັ້ນ ເຮົາມາເບິ່ງວິທີການຕັ້ງຊື່ຕົວປ່ຽນໃຫ້ອ່ານງ່າຍ ແລະ ເປັນມາດຕະຖານໃຫ້ກັບທີມໃນການພັດທະນາກັນດີກວ່າ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ກ່ອນອື່ນໝົດ, ຢຸດຕັ້ງຊື່ທີ່ມັນບໍ່ໄດ້ສື່ຄວາມໝາຍໃດໆໄດ້ແລ້ວ&lt;/strong&gt;&lt;br&gt;
ຕົວຢ່າງ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ຊື່ທີ່ຍອດນິຍົມເຊັ່ນ:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ຊື່ທີ່ເຊີຍທີ່ສຸດເຊັ່ນ: &lt;code&gt;data&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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;data1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data_1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ຊື່ທີ່ເປັນຄຳຫຍໍ້ພໍເຊົາໄດ້ກະເຊົາ(ຍົກເວັ້ນ &lt;code&gt;id&lt;/code&gt;)ເຊັ່ນ:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;pos&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mod&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;inq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ຈຳພວກ local variable ທັງຫຼາຍກໍ່ເຊົາຕັ້ງຊື່ສັ້ນພຽງ 1 ຕົວອັກສອນໄດ້ແລ້ວເຊັ່ນ:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;
&lt;span class="c1"&gt;//ຢ່າມາບອກວ່າໃຊ້ 2 ຕົວອັກສອນລຽງກັນແລ້ວຊິລອດໃດ, ກອງຢູ່ນຳກັນນີ້ແຫຼະ&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;xx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;yy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;zz&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ອີກຂໍ້ທີສຳຄັນ ແລະ ພົບຫຼາຍເລີຍກໍ່ແມ່ນ: ການສະກົດຄຳສັບຜິດໆໃນການຕັ້ງຊື່(ແນະນຳລົງ spell check extendsion ໄວ້)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ຍັງບໍ່ໝົດພຽງເທົ່ານີ້, paper ຫົວຂໍ້ Linguistic antipatterns: what they are and how developers perceive them ໄດ້ອະທິບາຍເຖິງບັນຫາທີ່ເກີດຂຶ້ນຊ້ຳໆໃນການພັດທະນາ software ເຊັ່ນ: ການຕັ້ງຊື່, ເອກະສານ ແລະ ການອະທິບາຍໜ້າທີ່ການເຮັດວຽກຂອງລະບົບ ເຊິ່ງໄດ້ສະຫຼຸບໄວ້ 17 ຂໍ້ດັ່ງນີ້:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Getter method&lt;/code&gt; ເຮັດວຽກຫຼາຍກວ່າການ &lt;code&gt;return&lt;/code&gt; ຄ່າກັບມາໂດຍບໍ່ມີເອກະສານມາອະທິບາຍ&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isXXX method&lt;/code&gt; ທຳການ &lt;code&gt;return&lt;/code&gt; ຄ່າອື່ນໆທີ່ບໍ່ແມ່ນ &lt;code&gt;boolean&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Setter method&lt;/code&gt; ທຳການ &lt;code&gt;return&lt;/code&gt; ຄ່າກັບອອກມາໄດ້&lt;/li&gt;
&lt;li&gt;ຊື່ຂອງ &lt;code&gt;method&lt;/code&gt; ບອກວ່າ &lt;code&gt;return&lt;/code&gt; ຄ່າພຽງຄ່າດຽວ, ແຕ່ໃນຄວາມເປັນຈິງພັດສົ່ງ &lt;code&gt;List/Array&lt;/code&gt; ຫຼື &lt;code&gt;Null&lt;/code&gt; ອອກມາເຊັ່ນ &lt;code&gt;List getUser()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Comment&lt;/code&gt; ຂອງ &lt;code&gt;method&lt;/code&gt; ບອກວ່າມີເງື່ອນໄຂນັ້ນນີ້, ແຕ່ໃນ code ພັດບໍ່ມີ&lt;/li&gt;
&lt;li&gt;ໃນ &lt;code&gt;method&lt;/code&gt; ມັກຈະມີການ validate ຂໍ້ມູນ, ແຕ່ບໍ່ແຈ້ງຄວາມຜິດພາດໃດໆອອກມາເລີຍ ເຮັດວຽກໄດ້ໃນກໍລະນີທີ່ສຳເລັດເທົ່ານັ້ນໂດຍທີ່ບໍ່ມີເອກະສານໃດມາອະທິບາຍ&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Getter method&lt;/code&gt; ບໍ່ທຳການ &lt;code&gt;return&lt;/code&gt; ຄ່າຫຍັງເລີຍ&lt;/li&gt;
&lt;li&gt;ຊື່ຂອງ &lt;code&gt;method&lt;/code&gt; ບໍ່ສື່ເຖິງການເຮັດວຽກຕົວຈິງເຊັ່ນ: &lt;code&gt;void isValid()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;method&lt;/code&gt; ທີ່ທຳການແປງຄ່າຈາກຄ່າໜຶ່ງໄປເປັນອີກຄ່າໜຶ່ງ ບໍ່ທຳການ &lt;code&gt;return&lt;/code&gt; ຄ່າອອກມາ&lt;/li&gt;
&lt;li&gt;ຊື່ຂອງ &lt;code&gt;method&lt;/code&gt; ບອກວ່າ &lt;code&gt;return&lt;/code&gt; ຄ່າຫຼາຍກວ່າ 1 ຕົວເຊັ່ນ: &lt;code&gt;List/Array&lt;/code&gt; ແຕ່ໃນຄວາມເປັນຈິງພັດສົ່ງຄ່າດຽວກັບມາເຊັ່ນ: &lt;code&gt;int getUsers()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;ຊື່ &lt;code&gt;method&lt;/code&gt; ກັບຊະນິດຂອງການ &lt;code&gt;return&lt;/code&gt; ຂັດແຍ່ງກັນ&lt;/li&gt;
&lt;li&gt;ຊື່ &lt;code&gt;method&lt;/code&gt; ກັບ &lt;code&gt;Comment&lt;/code&gt; ຂອງ &lt;code&gt;method&lt;/code&gt; ຂັດແຍ່ງກັນ&lt;/li&gt;
&lt;li&gt;ຊື່ຕົວປ່ຽນເປັນເອກະພົດ ແຕ່ມີຄ່າເປັນພະຫູພົດເຊັ່ນ: &lt;code&gt;List User&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;ຊື່ຕົວປ່ຽນເປັນພະຫູພົດ ແຕ່ມີຄ່າເປັນເອກະພົດເຊັ່ນ: &lt;code&gt;List Users&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;ຊື່ບອກວ່າເປັນຊະນິດ &lt;code&gt;boolean&lt;/code&gt; ແຕ່ຄວາມຈິງພັດບໍ່ແມ່ນ(ເຈົ້າຫຼອກລວງຂ້ອຍ)&lt;/li&gt;
&lt;li&gt;ຊື່ ແລະ ຊະນິດຂໍ້ມູນຂອງຕົວປ່ຽນຂັດແຍ່ງກັນ&lt;/li&gt;
&lt;li&gt;ຊື່ ແລະ &lt;code&gt;Comment&lt;/code&gt; ຂອງຕົວປ່ຽນຂັດແຍ່ງກັນ&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ເຮົາລອງມາສຳຫຼວດໂຕເອງເບິ່ງວ່າເຮົາມີພຶດຕິກຳດ້ານເທິງ ຫຼື ບໍ່?, ແຕ່ໂດຍສ່ວນຕົວຜູ້ຂຽນເອງຂໍຮັບບາບໄປເຕັມໆແຕ່ພຽງຜູ້ດຽວ(ຂ້ານ້ອຍຜິດໄປແລ້ວ ງ່າາາາາາາາ)&lt;/p&gt;

&lt;p&gt;ແຕ່ເຖິງຢ່າງໃດກໍ່ຕາມຢ່າຟ້າວທໍ້ໃຈເທື່ອ, ທຸກບັນຫາມີທາງເຂົ້າສະເໝີ ເຮົາມາລອງປັບປ່ຽນວິທີການຕັ້ງຊື່ໃຫ້ເປັນມາດຕະຖານຫຼາຍຂຶ້ນ, ເພື່ອເປັນບຸນຕາໃຫ້ແກ່ຜູ້ພົບເຫັນກັນດີກວ່າ.&lt;br&gt;
&lt;strong&gt;ຂໍ້ຄວນປະຕິບັດໃນການຊຳລະບາບທັງປວງ&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ຕັ້ງຊື່ຕົວປ່ຽນໃຫ້ອ່ານແລ້ວເຂົ້າໃຈ(ໝາຍເຖິງຄົນອື່ນຕ້ອງເຂົ້າໃຈນຳໃດ ບໍ່ແມ່ນເຂົ້າໃຈແຕ່ຜູ້ດຽວ 5555)&lt;/strong&gt;
ຊື່ຂອງຕົວປ່ຽນຄວນຈະອະທິບາຍຈຸດປະສົງຂອງມັນໄດ້ຢ່າງຊັດເຈນ, ຫຼີກລ່ຽງການໃຊ້ຄຳທີ່ອ່ານແລ້ວເຂົ້າໃຈຍາກ
*ເລືອກ case ໃນການຕັ້ງຊື່ໃຫ້ເໝາະສົມເຊັ່ນ: camel case
ຕົວຢ່າງ:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mydate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YYYY/MM/DDD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YYYY/MM/DDD&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;ຕັ້ງຊື່ຕົວປ່ຽນໃຫ້ Search ໄດ້ງ່າຍ&lt;/strong&gt;
ບາງບົດຄວາມອາດຈະບອກວ່າ: ຢ່າສ້າງຕົວປ່ຽນໃນເມື່ອເຮົາກໍ່ສາມາດໃຊ້ Monomorphic Forms ໄດ້, ເຊິ່ງເຮົາບໍ່ຄວນທີ່ຈະຂະຫຍາຍສິ່ງເຫຼົ່ານີ້ເພື່ອໃຊ້ &lt;code&gt;Constants&lt;/code&gt; ເພາະຈະເຮັດໃຫ້ code ອ່ານຍາກ ແລະ search ຍາກຂຶ້ນ, ແຕ່ສິ່ງທີ່ຄວນເຮັດກໍ່ຄື ເກັບຄ່າເຫຼົ່ານັ້ນໄວ້ໃນຕົວປ່ຽນ &lt;code&gt;const&lt;/code&gt; ແລະ ໃຊ້ CONSTANT_CASE ໃນການຕັ້ງຊື່ຕົວປ່ຽນ.
ຕົວຢ່າງ:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 86400000 ຄືອີ່ຫຍັງກ່ອນ?&lt;/span&gt;
&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blastOff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;86400000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//ປະກາດຕົວປ່ຽນ constant ດ້ວຍຕົວອັກສອນໃຫຍ່&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MILLISECONDS_PER_DAY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="c1"&gt;//86400000&lt;/span&gt;
&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blastOff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MILLISECONDS_PER_DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ຫຼີກລ່ຽງການຕັ້ງຊື່ຕົວປ່ຽນທີ່ຕ້ອງໄດ້ຄາດເດົາ&lt;/strong&gt;
ມັນຈະເປັນການດີທີ່ເຮົາຈະຕັ້ງຊື່ຕົວປ່ຽນໃຫ້ຊັດເຈນພາຍໃນ &lt;code&gt;array.forEach()&lt;/code&gt; ແທນທີ່ຈະໃຊ້ຕົວຫຍໍ້ທີ່ບໍ່ສື່ຄວາມໝາຍໃດໆເລີຍ, ເຊິ່ງແນ່ນອນວ່າມັນອາດຈະແຈກຢາພາລາໃຫ້ພາຍຫຼັງກໍ່ເປັນໄດ້.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;carMake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Honda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;carModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Civic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;carColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gray&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;paintCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&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;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;carColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Honda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Civic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gray&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;paintCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&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;car&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="nx"&gt;color&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ຫຼີກລ່ຽງສິ່ງທີ່ບໍ່ຈຳເປັນ&lt;/strong&gt;
ຖ້າຫາກຊື່ &lt;code&gt;Class&lt;/code&gt; ຫຼື &lt;code&gt;Object&lt;/code&gt; ບົ່ງບອກຢູ່ແລ້ວວ່າພວກມັນຫຍໍ້ມາຈາກຫຍັງ ກໍ່ບໍ່ຈຳເປັນທີ່ຈະຕ້ອງເພີ່ມຂໍ້ມູນນັ້ນລົງໃນຊື່ຕົວປ່ຽນອີກ. ຈາກຕົວຢ່າງດ້ານລຸ່ມ: ເຮົາຮູ້ຢູ່ແລ້ວວ່າເຮົາກຳລັງເວົ້າເຖິງ &lt;code&gt;Car&lt;/code&gt; ຫຼື &lt;code&gt;paintCar&lt;/code&gt; ດັ່ງນັ້ນ ເຮົາກໍ່ບໍ່ຈຳເປັນທີ່ຈະຕ້ອງເພີ່ມຄຳວ່າ &lt;code&gt;car&lt;/code&gt; ໃນຕົວປ່ຽນຊ້ຳອີກຮອບ.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;carMake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Honda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;carModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Civic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;carColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gray&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;paintCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&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;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;carColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;make&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Honda&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Civic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gray&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;paintCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&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;car&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="nx"&gt;color&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ໃຊ້ &lt;code&gt;Default Arguments&lt;/code&gt; ໃນ &lt;code&gt;Functions&lt;/code&gt;&lt;/strong&gt;
ຫຼີກລ່ຽງການໃຊ້ Short-Circuiting ຫຼື Conditionals ໃນ Functions ເພື່ອເຮັດໃຫ້ Code ຂອງເຮົາ Clean ແລະ ທີ່ສຳຄັນກວ່ານັ້ນຄື: ຈົ່ງຈື່ໄວ້ວ່າ ສະເພາະ &lt;code&gt;Undefined Arguments&lt;/code&gt; ເທົ່ານັ້ນທີ່ຈະໄດ້ຮັບຄ່າໂດຍ Function ຂອງເຮົາ Default Values ຈະບໍ່ແທນທີ່ Falsy Values ອື່ນໆ.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createMicrobrewery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breweryName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home Brew Co.&lt;/span&gt;&lt;span class="dl"&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;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createMicrobrewery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home Brew Co.&lt;/span&gt;&lt;span class="dl"&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;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ໃຊ້ Default Arguments ຢ່າງຊານສະຫຼາດ&lt;/strong&gt;
ຕາມກົດເກນທົ່ວໄປແມ່ນ ໃຫ້ຈຳກັດຈຳນວນ Arguments ຂອງ Function ໄວ້ປະມານ 2-3 Arguments. ຫາກມີການຮັບ Arguments ເປັນຈຳນວນຫຼາຍກໍ່ອາດຈະມີຄວາມເປັນໄປໄດ້ທີ່ Function ຂອງເຮົາອາດຈະເຮັດວຽກຫຼາຍຢ່າງເກີນໄປ, ແຕ່ຖ້າຫາກຢາກໃຊ້ຫຼາຍ Arguments ແມ່ນແນະນຳໃຫ້ໃຊ້ JS Object ເປັນ Argument ເພື່ອໃຫ້ເກີດຄວາມຊັດເຈນວ່າມີ Properties ໃດແດ່ທີ່ Function ຕ້ອງການ ແລະ ເຮົາສາມາດໃຊ້ ES6 Destructuring Syntax ໄດ້.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createMenu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buttonText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cancellable&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;createMenu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Foo&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="s2"&gt;Bar&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="s2"&gt;Baz&lt;/span&gt;&lt;span class="dl"&gt;"&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;span class="c1"&gt;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createMenu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buttonText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cancellable&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;createMenu&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="s2"&gt;Foo&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;buttonText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Baz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;cancellable&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;ແຕ່ລະ Functions ຄວນເຮັດໜ້າທີ່ພຽງຢ່າງດຽວ&lt;/strong&gt;
ຢ່າລືມວ່າ Functions ໃດມີໄວ້ເພື່ອເຮັດຫຍັງ, ໝາຍຄວາມວ່າພະຍາຍາມຂຽນ Code ຂອງເຮົາໃຫ້ເປັນ Module ແລະ ພະຍາຍາມຂຽນ Function ໃຫ້ມີຂະໜາດນ້ອຍລົງເພື່ອໃຫ້ມັນເຮັດໜ້າທີ່ຢ່າງໃດຢ່າງໜຶ່ງພຽງຄັ້ງດຽວ, ສິ່ງທີ່ຈະຊ່ວຍໃຫ້ໝັ້ນໃຈໄດ້ວ່າ Code ຂອງເຮົານັ້ນງ່າຍຕໍ່ການ Test ແລະ ທຳຄວາມເຂົ້າໃຈ, ທີ່ສຳຄັນຄືຢ່າຕັ້ງຈຸດປະສົງຫຼາຍໆຢ່າງພາຍໃນ Function ດຽວ.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailClients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clients&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;clients&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;client&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;clientRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&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;clientRecord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;()){&lt;/span&gt;
   &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&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;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailClients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clients&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;clients&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;isActiveClient&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;email&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;isActiveClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&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;clientRecord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;ຕັ້ງຊື່ Functions ໃຫ້ອ່ານແລ້ວເຂົ້າໃຈ&lt;/strong&gt;
ກວດສອບໃຫ້ແນ່ໃຈວ່າເຮົາຕັ້ງຊື່ Functions ທີ່ສາມາດເຂົ້າໃຈໄດ້ຢ່າງຊັດເຈນວ່າ Functions ນັ້ນໃຊ້ໄວ້ເຮັດຫຍັງ, ການຕັ້ງຊື່ Function ທີ່ມີຄວາມໝາຍບໍ່ຊັດເຈນຈະເຮັດໃຫ້ຄົນທີ່ມາອ່ານ Code ຈະຕ້ອງເບິ່ງຄຳ Definition ແລະ Logic ຂອງ Function ເພື່ອທຳຄວາມເຂົ້າໃຈໜ້າທີ່ຂອງແຕ່ລະ Function, ເຊິ່ງກໍ່ຈະເຮັດໃຫ້ເສຍເວລາຕື່ມໄປອີກ.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addToDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;month&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="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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;//ເວລາເອີ້ນໃຊ້ມັນກໍ່ຍາກທີ່ຈະເຂົ້າໃຈໄດ້ຈາກຊື່ຟັງຊັ່ນວ່າໄດ້ເພີ່ມຫຍັງ&lt;/span&gt;
&lt;span class="nx"&gt;addToDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&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="c1"&gt;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addMonthToDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;date&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="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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;addMonthToDate&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="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ຫຼີກລ່ຽງການໃຊ້ Code ທີ່ຊ້ຳຊ້ອນກັນ, ເຮັດໃຫ້ Code ສັ້ນລົງ ແລະ Clean ຂຶ້ນ&lt;/strong&gt;&lt;br&gt;
ສິ່ງທີ່ເຮັດໃຫ້ເຈັບຫົວທີ່ສຸດກໍ່ຄື: ມີການໃຊ້ Code ແບບດຽວຊ້ຳໆກັນໃນຫຼາຍໆ Sections ຂອງ Code, ເຊິ່ງມັນມັກຈະເກີດຂຶ້ນເນື່ອງຈາກ Logic ບາງຢ່າງມີການເຮັດວຽກແຕກຕ່າງກັນພຽງເລັກນ້ອຍ, ແຕ່ເຖິງຢ່າງໃດກໍ່ຕາມ ລອງຄິດພາບວ່າຖ້າຫາກເຮົາພົບ Bud ໃນ Logic ເຮົາຕ້ອງໄດ້ນຳໄປແກ້ໃນທຸກໆ Sections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ບໍ່ຄວນໃຊ້ Flags ເປັນ Function Parameters&lt;/strong&gt;&lt;br&gt;
ເຫດຜົນທີ່ເຮົາບໍ່ຄວນໃຊ້ Flags ເປັນ Funstion Parameters ມີພຽງຢ່າງດຽວຄື: Function ຂອງເຮົາເຮັດຫຼາຍໜ້າທີ່ ແລະ ໃນຂໍ້ທີ່ຜ່ານມາກໍ່ບອກແລ້ວວ່າມັນເປັນແນວທາງທີ່ບໍ່ຄວນເຮັດ, ດັ່ງນັ້ນ ແນະນຳໃຫ້ແບ່ງ Function ອອກເປັນ 2 Functions ແທນ.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//bad&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;temp&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`./temp/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;//good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;createTempFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`./temp/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;br&gt;
&lt;a href="https://www.somkiat.cc/meaningful-name/"&gt;https://www.somkiat.cc/meaningful-name/&lt;/a&gt;&lt;br&gt;
ແລະ &lt;br&gt;
&lt;a href="https://www.techstarthailand.com/blog/detail/10-Tips-to-write-cleaner-JavaScript-code/2147"&gt;https://www.techstarthailand.com/blog/detail/10-Tips-to-write-cleaner-JavaScript-code/2147&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Clean Architecture using React TypeScript</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Thu, 29 Sep 2022 08:21:10 +0000</pubDate>
      <link>https://dev.to/phatsss/clean-architecture-using-react-typescript-1ojf</link>
      <guid>https://dev.to/phatsss/clean-architecture-using-react-typescript-1ojf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt; ແມ່ນແນວຄິດທີ່ໃຊ້ໄດ້ກັບທຸກໆພາສາຂອງການຂຽນໂປຣແກຣມ, ໝາຍຄວາມວ່າຄວາມເຂົ້າໃຈກ່ຽວກັບ Architecture ນີ້ຈະບໍ່ໄດ້ຈຳກັດສະເພາະໃນບໍລິບົດຂອງພາສາໂປຣແກຣມພຽງຢ່າງດຽວ. ເຮົາຕ້ອງເຂົ້າໃຈແນວຄິດໂດຍທົ່ວໄປຂອງມັນເພື່ອເຂົ້າໃຈເຖິງສາເຫດ ແລະ ປະໂຫຍດຂອງ Architecture ນີ້, ເຊິ່ງວິທີການນີ້ຈະຄ້າຍຄືກັບການອອກແບບ ຫຼື SOLID pattern. ສະຫຼຸບກໍ່ຄືມັນບໍ່ໄດ້ຖືກຄິດຄົ້ນຂຶ້ນມາສຳຫຼັບພາສາໂປຣແກຣມໃດໜຶ່ງ ແຕ່ມັນສາມາດນຳໃຊ້ແນວຄິດນີ້ກັບພາສາອື່ນໆໄດ້ເຊັ່ນກັນກັບແນວຄິດຂອງ OOP.&lt;/p&gt;

&lt;p&gt;ໝາຍເຫດ: ເປົ້າໝາຍຫຼັກຂອງ Clean Architecture ແມ່ນເພື່ອໃຫ້ Code ຂອງເຮົາລະອຽດຂຶ້ນ, ບຳລຸງຮັກສາໄດ້ ແລະ ທົດສອບໄດ້. ໃນໂປຣເຈັກນ້ອຍໆຖ້າຫາກເຮົາຂຽນແບບ Pure JS ໄວກວ່າການໃຊ້ Architecture ແລະ /test ກໍ່ບໍ່ຈຳເປັນຕ້ອງຫັນມາໃຊ້(ຖ້າບໍ່ມີຄວາມຈຳເປັນ), ແຕ່ໃນກໍລະນີທີ່ໂປຣເຈັກເຮົາມີຂະໜາດກາງ-ໃຫຍ່ທີ່ເຮັດວຽກຮ່ວມກັບ developer ຫຼາຍໆຄົນ ແລະ ບາງຄັ້ງກໍ່ອາດຈະໄດ້ແກ້ code ຂອງຄົນອື່ນເຮົາກໍ່ຄວນໃຊ້ເທາະ ຈຶ່ງຈະບໍ່ກັບມາເຈັບຫົວຕອນແກ້ Code ຄືນ.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ໂຄງສ້າງທີ່ດີໃນດ້ານຂອງການພັດທະນາໂປຣແກຣມໃດໜຶ່ງຂຶ້ນມາຄວນແບ່ງ UI,Database ແລະ Business Logic ອອກຈາກກັນເພື່ອໃຫ້ຄວາມອິດສະລະຕໍ່ການ Test, ຕົວຢ່າງ: ຖ້າຢາກ test ໃນຝັ່ງຂອງ business logic ກໍ່ບໍ່ຕ້ອງກັງວົນເລື່ອງຂອງ UI ແລະ Database. ແລະ ໃນທາງກັບກັນ ຖ້າຢາກຈະ test ຝັ່ງຂອງ UI ກໍ່ຄວນບໍ່ມີສ່ວນຂອງ Business Logic ແລະ Database ມາກ່ຽວຂ້ອງ. ເມື່ອທຸກສ່ວນຖືກແຍກອອກຈາກກັນຢ່າງອິດສະລະແລ້ວເວລາ requirement ປ່ຽນໄປກໍ່ຈະເຮັດໃຫ້ການເພີ່ມ ຫຼື ແກ້ໄຂໄດ້ງ່າຍເຊິ່ງມັນຈະບໍ່ກະທົບທັງລະບົບ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ເປັນຫຍັງຈຶ່ງໃຊ້ Architecture?
&lt;/h2&gt;

&lt;p&gt;ຄວາມຈຳເປັນໃນການໃຊ້ Architecture ກໍ່ຄືມັນຈະປະຢັດເວລາໃນລະຫວ່າງການພັດທະນາ, ການບຳລຸງຮັກສາລະບົບ, ການທົດສອບ ແລະ ການຂະຫຍາຍໂປຣເຈັກໃນອະນາຄົດທີ່ໃຊ້ເວລາໃນການພັດທະນາດົນ.&lt;br&gt;
ສະຫຼຸບງ່າຍໆເລີຍກໍ່ຄື: ຖ້າວາງໂຄງບໍ່ດີຕັ້ງແຕ່ເລີ່ມມັນຍິ່ງຈະມີຄ່າໃຊ້ຈ່າຍທີ່ສູງຖ້າຫາກມີການປ່ຽນແປງໃນອະນາຄົດ, ສະນັ້ນຕ້ອງຄິດເຜື່ອອະນາຄົດໄວ້ນຳ.&lt;/p&gt;

&lt;h2&gt;
  
  
  ຄຳຈຳກັດຄວາມຂອງ Clean Architecture ໂດຍທົ່ວໄປ
&lt;/h2&gt;

&lt;p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxtln5g7xjk9l9oo74pc.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxtln5g7xjk9l9oo74pc.png" alt="Clean Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ແນວຄິດຫຼັກທີ່ຢູ່ເບື້ອງຫຼັງຂອງ diagram ນີ້ແມ່ນການແບ່ງ Application ອອກເປັນ layer (ມີຈັກ layer ກໍ່ໄດ້), ໂດຍທີ່ layer ທີ່ຢູ່ຊັ້ນໃນຈະບໍ່ຮູ້ຈັກ layer ທີ່ຢູ່ຊັ້ນນອກ ແລະ ແຕ່ລະ layer ຈະຊີ້ໄປຫາ Layer ທີ່ຢູ່ຊັ້ນໃນ(Outer Layer to Inner Layer). ຍິ່ງ layer ຢູ່ໄກຈາກສູນກາງເທົ່າໃດຍິ່ງເຫັນລາຍລະອຽດກ່ຽວກັບ Application ທີ່ເປັນ “non-business” ຫຼາຍຂຶ້ນເທົ່ານັ້ນ.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ຈາກທີ່ໄດ້ອະທິບາຍມາແລ້ວວ່າໂຄງສ້າງທີ່ດີໃນການພັດທະນາກໍ່ການແຍກສ່ວນຂອງ UI, Database ແລະ Business Logic ອອກຈາກກັນ, ເຊິ່ງ Clean Architecture ກໍ່ຕອບໂຈດໃນຂະບວນການນີ້. ຈະເຫັນໄດ້ວ່າ Clean Architecture ມີການແບ່ງ layer ໄວ້ຢ່າງຊັດເຈນເຮັດໃຫ້ສາມາດ test ໄດ້ງ່າຍ ແລະ Maintance ພາຍຫຼັງໄດ້ງ່າຍອີກນຳ. Clean Architecture ຈະມີຂໍ້ຕົກລົງຮ່ວມກັນຢູ່ວ່າ layer ຊັ້ນນອກຈະປຽບເໝືອນກົນໄກຕ່າງໆ ແລະ layer ຊັ້ນໃນຈະປຽບເໝືອນ policy ຕ່າງໆ, ຖ້າຫາກ layer ຊັ້ນນອກຕ້ອງການ referrence ໄປຫາ layer ຊັ້ນໃນຈະຕ້ອງເຮັດຕາມ policy ທີ່ກຳນົດໄວ້ ໂດຍທີ່ layer ຊັ້ນໃນຈະບໍ່ຮັບຮູ້ເຖິງ layer ທີ່ຢູ່ຊັ້ນນອກໄດ້, ຊື່ຕ່າງໆຂອງ layer ຊັ້ນນອກຈະບໍ່ຖືກອ້າງອີງເຖິງ layer ຊັ້ນໃນ ແລະ layer ຊັ້ນນອກຈະບໍ່ສົ່ງຜົນກະທົບຕໍ່ layer ຊັ້ນໃນ.&lt;br&gt;
ງົງແມ່ນບໍ່? ຂ້ອຍກະງົງຄືກັນ 🤣🤣🤣, ເພື່ອງົງຕື່ມ ເຮົາໄປຕໍ່ຍາວໆກັນເລີຍ 555&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entities&lt;/strong&gt;: ເປັນ Layer ຊັ້ນໃນສຸດເຊິ່ງຈະບັນຈຸ business logic ຂອງ Application ແລະ ຈະບໍ່ມີ platform dependencies, ເຊິ່ງ Entities ຈະອະທິບາຍເຖິງ business logic ຂອງ Application ຢ່າງດຽວເທົ່ານັ້ນ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ຕົວຢ່າງ: ໃນ Class ຂອງ "cart" ເຮົາສາມາດເພີ່ມ item, ລຶບ item, etc. ເຊິ່ງໃນ Layer ນີ້ຈະບໍ່ກ່ຽວກັບບັນດາເຟຣມເວີກຕ່າງໆທີ່ເຮົາໃຊ້ເຊັ່ນ React, Databases ເລີຍ.&lt;/p&gt;

&lt;p&gt;ປລ. platform dependencies ຂ້າງເທິງແມ່ນເວົ້າສະເພາະເຈາະຈົງເຖິງບັນດາ libraries ຕ່າງໆເຊັ່ນ: React, Angular, Express, etc. ແມ່ນຈະບໍ່ໄດ້ເອີ້ນໃຊ້ໃນ Layer ນີ້.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ສະຫຼຸບແບບ 5 ວິ: Entities ປຽບເໝືອນ Data Model ຂອງເຮົາທີ່ຈຳແນກວ່າ Data ເຮົາຈະເກັບຫຍັງແນ່ ແລະ ມີ Structure ແນວໃດ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use cases&lt;/strong&gt;: ໃນ layer ທີ 2 ຂອງ diagram ນີ້ຈະບັນຈຸ use cases(Interactors). Use cases ແມ່ນສ່ວນທີ່ອະທິບາຍເຖິງວິທີການໂຕ້ຕອບກັບ Entities ໃນບໍລິບົດຂອງ Application ຂອງເຮົາ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ຕົວຢ່າງ: ຖ້າຫາກ Entity ຂອງ cart ຮູ້ຈັກພຽງແຕ່ວ່າໂຕມັນເອງສາມາດເພີ່ມ item, ໃນທີ່ນີ້ use case ເຮົາກໍ່ຮູ້ວ່າມັນສາມາດນຳເອົາ item ຈາກ cart ແລະ ສົ່ງ item ເຫຼົ່ານັ້ນໄປສູ່ repository.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ສະຫຼຸບແບບ 5 ວິ: Use cases ເປັນສ່ວນທີ່ເກັບ Business Logic ຕ່າງໆແລ້ວເອີ້ນໃຊ້ Entity ອີກເທື່ອໜຶ່ງ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gateways, Presenters, etc&lt;/strong&gt;. ໃນທີ່ນີ້ Gateways = Repositories, Presenters = View Models. ເຊິ່ງເປັນ layer ທີ່ມີໜ້າທີ່ໃນການເຊື່ອມຕໍ່ລະຫວ່າງ business rules ຂອງ application ແລະ platform ສ່ວນຕ່າງໆຂອງລະບົບ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ຕົວຢ່າງ: repositories ຈະມີ interface ທີ່ມີການ implement classes ໄວ້ເພື່ອ access APIs ຫຼື repositories ແລະ View Model interface ຈະໃຊ້ເພື່ອເຊື່ອມຕໍ່ກັບ React Component ດ້ວຍການເອີ້ນໃຊ້ business logic.&lt;/p&gt;

&lt;p&gt;ປລ. ໃນຕົວຢ່າງຂອງເຮົາ Use cases ແລະ Repositories ຈະຢູ່ໃນລຳດັບທີ່ແຕກຕ່າງກັນ ເພາະວ່າການເຮັດວຽກສ່ວນໃຫຍ່ຂອງ front-end ແມ່ນຮັບ ແລະ ສົ່ງ data ຜ່ານ API ເປັນຫຼັກ.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ສະຫຼຸບແບບ 5 ວິ:ອາດເວົ້າໄດ້ວ່າ layer ນີ້ແມ່ນສ່ວນທີ່ເອົາໄວ້ແປງຮູບແບບຂອງຂໍ້ມູນເຊັ່ນ ຢາກແປງຮູບແບບຂໍ້ມູນຈາກ format ໃດໆກໍ່ຕາມໃຫ້ເປັນ format ທີ່ application ເຮົາເຂົ້າໃຈ ແລະ ໃຊ້ໄດ້ງ່າຍ. ຕົວຢ່າງ ແປງຈາກ json format ເປັນ object ທີ່ເຮົາຕ້ອງການ, ເຊິ່ງເຮົາເອີ້ນສິ່ງທີ່ເຮົາໜ້າທີ່ເຫຼົ່ານີ້ວ່າ Adapter.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;External interfaces&lt;/strong&gt;: ເປັນ platform dependent layer, ໃນຊັ້ນນີ້ເຮົາຈະເຫັນການ direct access ໄປ API, React Components, etc. ມັນເປັນ layer ທີ່ຍາກໃນການ test ແລະ build abstraction.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ສະຫຼຸບແບບ 5 ວິ: layer ນີ້ເປັນສ່ວນທີ່ຈັດການກັບ framework ທີ່ເຮົາໃຊ້ໃນໂປຣເຈັກ ໃນສ່ວນນີ້ເຮົາອາດຈະບໍ່ໄດ້ຂຽນ code ຫຼາຍແຕ່ກໍ່ເປັນສ່ວນທີ່ສຳຄັນເພາະເປັນສ່ວນທີ່ເອົາໄວ້ໃຊ້ຕິດຕໍ່ກັບ framework ຕ່າງໆທີ່ເຮົາໃຊ້ເຊັ່ນ: ການຂຽນ code ເພື່ອສ້າງ database connection ເປັນຕົ້ນ.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Clean Architecture ສຳຫຼັບ frontend
&lt;/h2&gt;

&lt;p&gt;ຖ້າອ່ານຫົວຂໍ້ດ້ານເທິງແລ້ວຍັງບໍ່ເຫັນພາບເທື່ອ, ເຮົາມາລອງເບິ່ງວ່າຖ້າເອົາມາໃຊ້ໃນເບື້ອງຂອງ frontend ແລ້ວ ມັນອອກມາໜ້າຕາແບບໃດ.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr67k7y3wracuinlrj71u.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr67k7y3wracuinlrj71u.png" alt="Clean Architecture for frontend"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Entities&lt;/strong&gt;: ຄວາມໝາຍຂອງ Entities ກໍ່ຈະຄ້າຍຄືກັບຄຳອະທິບາຍດ້ານເທິງ, ເຊິ່ງ Entities ຈະເປັນວິທີການໃນການເກັບ state ແລະ ສ່ວນໃຫຍ່ກໍ່ມັກໃຊ້ເພື່ອຈຸດປະສົງນີ້ເປັນຫຼັກ.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repository interfaces&lt;/strong&gt;: ເປັນ Interfaces ທີ່ໃຊ້ເພື່ອເຂົ້າເຖິງ API, database, storages, etc. ມັນອາດຈະເບິ່ງຄືແປກໆທີ່ interfaces ຈະຢູ່ layer ຊັ້ນໃນກວ່າ use case, ເຖິງຢ່າງໃດກໍ່ຕາມໃນບໍລິບົດຂອງການໃຊ້ງານສະແດງໃຫ້ເຫັນວ່າ use case ຈະຮູ້ repositories ແຕ່ repositories ຈະບໍ່ຮູ້ຫຍັງກ່ຽວກັບ layer ຂອງ use case ເລີຍ ແລະ repositories ພັດຮູ້ກ່ຽວກັບ entities ນີ້ຈຶ່ງເປັນສາເຫດທີ່ເຮັດໃຫ້ interfaces ຢູ່ໃນ layer ນີ້.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;: ຄວາມໝາຍຂອງ use case ກໍ່ແມ່ນແບບດຽວກັນກັບດ້ານເທິງຄື Objects ທີ່ຈະນຳໃຊ້ໃນການ implement business logic ໃນບໍລິບົດຂອງ Application ຂອງເຮົາ(ຮູ້ວ່າຈະເຮັດຫຍັງກັບ entities ເຊັ່ນ: send, upload, filter, merge)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;View Models ແລະ View Interfaces&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;View Model - ແມ່ນໃຊ້ທົດແທນ Presenters ຈາກ diagram ທີ 1. ໃນໂປຣເຈັກຂອງເຮົາຈະໃຊ້ MVVP Architecture(instead of MVP\MVC\MV*), ອະທິບາຍໂດຍຫຍໍ້ຄື: ຄວາມແຕກຕ່າງຂອງ MVVP ມີພຽງຢ່າງດຽວຄື: Presenter ຈະຮູ້ກ່ຽວກັບ View ແລະ ວິທີການເອີ້ນ method ຂອງມັນ, ແຕ່ ViewModel ບໍ່ຮູ້ຈັກ View ແລະ ມີພຽງ method ດຽວທີ່ notify ເຖິງການປ່ຽນແປງຕ່າງໆ. View ເຮັດໜ້າທີ່ພຽງແຕ່ "monitor" state ຂອງ View Model. ຫຼັກການຂອງ MVVP ແມ່ນຈະເຮັດວຽກໄປໃນທິດທາງດຽວ(View → ViewModel) ໃນຂະນະທີ່ MVP ເຮັດວຽກແບບ 2 ທິດທາງ (View ︎← → Presenter), dependencies ໜ້ອຍລົງ ແລະ test ງ່າຍກວ່າ.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;View Interfaces - ໃນກໍລະນີນີ້, ຈະມີໜຶ່ງ class ພື້ນຖານສຳລັບ Views ທັງໝົດ, ໂດຍທີ່ View Model ຈະແຈ້ງເຕືອນ(notify) View ກໍຕໍ່ເມື່ອມີການປ່ຽນແປງໃດໜຶ່ງເກີດຂຶ້ນ. ເຊິ່ງຈະໃຊ້ onViewModelChanged() method ແລະ ນີ້ກໍ່ແມ່ນໜຶ່ງໃນຕົວຢ່າງຂອງ dependency inversion.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;External interfaces&lt;/strong&gt;: ຄວາມໝາຍຂອງຂໍ້ນີ້ກໍ່ເຊັ່ນດຽວກັນກັບ diagram ທີ 1, layer ນີ້ຈະບັນຈຸບັນດາ platform-dependent implementations ຕ່າງໆ. ໃນກໍລະນີທີ່ application ຂອງເຮົາພັດທະນາໂດຍໃຊ້ React components ແລະ implementations interfaces ເພື່ອເຂົ້າເຖິງ API (ຮູບປະກອບດ້ານລຸ່ມ), ເຖິງຢ່າງໃດກໍ່ຕາມໃນ layer ນີ້ເຮົາສາມາດໃຊ້ framework ໃດກໍ່ໄດ້(AngularJS, VueJS, ReactJS, ReactNative, etc.) ແລະ storage ໃດກໍ່ໄດ້(IndexDB, LocalStorage, etc.), ເຊິ່ງ Clean Architecture ຊ່ວຍໃຫ້ເຮົາສາມາດແຍກໃຊ້ສະເພາະ framework, libraries ແລະ technologies ໃດກໍ່ໄດ້. ດັ່ງນັ້ນເຮົາຈຶ່ງສາມາດ test ໄດ້ງ່າຍ ແລະ ຈະປ່ຽນໄປໃຊ້ framework ໃດກໍ່ໄດ້.&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwu32jxa1xpaempjffd8.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwu32jxa1xpaempjffd8.png" alt="implementations interface"&gt;&lt;/a&gt;&lt;br&gt;
arrow ສີແດງແມ່ນສະແດງເຖິງ flow ຂອງ data(ແຕ່ບໍ່ແມ່ນບັນດາ dependencies, dependency diagram ແມ່ນສະແດງຢູ່ diagram ດ້ານເທິງ), ບັນດາ structure ທີ່ກ່າວມາດ້ານເທິງກໍ່ສາມາດປ່ຽນແປງໃຫ້ເໝາະສົມກັບ application ທີ່ເຮົາພັດທະນາ.&lt;/p&gt;

&lt;h2&gt;
  
  
  ໃນການໃຊ້ງານຈິງເຮົາຈະວາງ Structures ໄດ້ດັ່ງນີ້
&lt;/h2&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpt7z2ycqptemzii39yq.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpt7z2ycqptemzii39yq.png" alt="clean architecture file structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;data&lt;/strong&gt; - ບັນຈຸບັນດາ classes ທີ່ໃຊ້ໃນການເຂົ້າເຖິງ data,ຖ້າປຽບທຽບໃສ່ diagram folder ນີ້ຈະເປັນ layer ຊັ້ນໃນສຸດຍ້ອນວ່າງໃນນີ້ຈະມີ classes ສຳລັບ implementing repository interfaces. ດັ່ງນັ້ນ classes ເຫຼົ່ານີ້ຈະຖືກໃຊ້ໃນການເຊື່ອມຕໍ່ກັບ API ແລະ platform dependent(local storage, cookies, etc.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;domain&lt;/strong&gt; - classes ເຫຼົ່ານີ້ບັນຈຸບັນດາ business logic, ໃນ folder ນີ້ຈະມີ Entities, Use Cases ແລະ Repository Interfaces. ໃນ entities folder ຈະແບ່ງເປັນ 2 folder ຍ່ອຍຄື: models ແລະ structures.&lt;br&gt;
&lt;strong&gt;models&lt;/strong&gt;: ເປັນບັນດາ logic ຕ່າງໆ ແລະ &lt;strong&gt;structures&lt;/strong&gt; ຈະເປັນ data structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;presentation&lt;/strong&gt; - folder ນີ້ບັນຈຸ View Models, View Interfaces ແລະ View (framework components).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ຈາກໂຄງສ້າງດ້ານເທິງມັນກໍ່ບໍ່ແມ່ນສິ່ງຕາຍຕົວທີ່ເຮົາຈະຕ້ອງກຳນົດແບບນີ້ເປະໆ, ສະນັ້ນ ເຮົາກໍ່ຕ້ອງປັບໃຊ້ຕາມຈຸດປະສົງ ແລະ ຄວາມເໝາະສົມ.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ສຸດທ້າຍນີ້ກໍ່ຫວັງວ່າບົດຄວາມນີ້ຈະເປັນປະໂຫຍດໃຫ້ແກ້ຜູ້ອ່ານບໍ່ຫຼາຍ ຫຼື ອາດຈະບໍ່ມີເລີຍ 5555, ແຕ່ຖ້າຢາກໃຫ້ຂຽນອະທິບາຍ Code ຕົວຈິງກໍ່ລອງທັກຫຼັງໄມມາ ຫຼື ຖິ້ມເມັ້ນປະໄວ້ດຽວຈະພະຍາຍາມກັບມາຂຽນຕໍ່.&lt;/p&gt;

&lt;p&gt;ບົດຄວາມນີ້ຖອດເອົາສະເພາະບາງສ່ວນມາຈາກ &lt;a href="https://medium.com/@rostislavdugin/the-clean-architecture-using-react-and-typescript-a832662af803" rel="noopener noreferrer"&gt;The Clean Architecture using React and TypeScript. Part 1: Basics&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Replace empty string to undefined value in Object (JS)</title>
      <dc:creator>phatsss</dc:creator>
      <pubDate>Wed, 17 Aug 2022 17:48:54 +0000</pubDate>
      <link>https://dev.to/phatsss/replace-empty-string-to-undefined-value-in-object-js-3mc5</link>
      <guid>https://dev.to/phatsss/replace-empty-string-to-undefined-value-in-object-js-3mc5</guid>
      <description>&lt;p&gt;just create function like:&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;replaceEmpty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&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;key&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="nx"&gt;newObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;removeEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="k"&gt;else&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;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="k"&gt;else&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;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;newObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newObj&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;that's all, hope this func can help U 😵‍💫&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
