Skip to main content
0
JavaScriptProgramming Language

เขียน JavaScript ยังไงให้ดูเป็นมือโปร

ภาษาโปรแกรมที่มีประโยชน์ในการนำไปใช้งานได้หลากหลาย ได้ทั้ง Frontend และ Backend อย่าง JavaScript เชื่อว่าทุกคนที่รู้จักการเขียนโปรแกรมก็ต้องรู้จักหรืออาจจะเคยเขียนกันมา วันนี้เราจะมาดูกันว่าจะเขียน JavaScript ยังไงให้ดูเป็นมือโปร

ตั้งชื่อให้สื่อความหมาย

ส่วนที่ง่ายที่สุดในการทำให้โค้ดของเราดูเป็นมือโปรก็คือการตั้งชื่อ ไม่ว่าจะเป็นตัวแปรหรือชื่อฟังก์ชัน เราควรหลีกเลี่ยงการตั้งชื่อด้วยตัวแปรที่ไม่สื่อความหมายหรือทำให้เกิดความเข้าใจผิด ตัวอย่างเช่น

function toAccounting(n) {
   if (n < 0) {
      return '(' + Math.abs(n) + ')'
   } else if (n >= 0) {
      return n
   }
}

สมมติให้มีฟังก์ชันคำนวนตัวเลขทางบัญชี แบบโค้ดด้านบนนี้ จะเห็นว่าการตั้งชื่อฟังก์ชันยังไม่สื่อความหมายชัดเจน “toAccounting” ถ้าเราไม่ได่เป็นคนเขียนฟังก์ชันนี้ขึ้นมาหรือว่าโค้ดทั้งหมดมีหลายร้อยบรรทัด เวลาที่เราย้อนกลับมาดูก็อาจจะต้องเสียเวลาทำความเข้าใจว่าฟังก์ชันตัวนี้มีไว้เพื่ออะไร แล้วใช้งานยังไง และพารามิเตอร์ที่รับเข้าไปก็ชื่อว่า “n” ยิ่งทำให้ชวนสับสวนเข้าไปใหญ่ว่าต้องใส่ค่าอะไรเข้าไป เราสามารถเปลี่ยนฟังก์ชันนี้ให้มีชื่อที่ดีขึ้นได้ เช่น 

  • “toAccounting” >> “numberToAccounting”
  • “n” >> “number”

โค้ดใหม่ของเราจะได้เป็นแบบนี้

function numberToAccounting(number) {
   if (number < 0) {
      return '(' + Math.abs(number) + ')'
   } else if (number >= 0) {
      return number
   }
}

ฟังก์ชันควรรีเทิร์นค่าเพียงชนิดเดียว

จากฟังก์ชัน numberToAccounting จะเหนว่าใน if กับ else มีการ return ค่าออกมาต่างชนิดกัน โดยถ้าหากเข้าเงื่อนไข if จะได้ผลลัพธ์เป็น ข้อความ(string)แต่ถ้าเข้าใน else จะได้ผลลัพธ์เป็น ตัวเลข(number) เช่น

function numberToAccounting(number) {
   if (number < 0) {
      return '(' + Math.abs(number) + ')'
   } else if (number >= 0) {
      return number
   }
}
 
console.log(numberToAccounting(-5))
console.log(typeof numberToAccounting(-5))
console.log(numberToAccounting(10))
console.log(typeof numberToAccounting(10))

ผลลัพธ์

(5)
string
10
number

เราต้องเลือกว่าจะให้ฟังก์ชันของเรา return เป็นข้อความหรือตัวเลข สมมติเราเลือกข้อความเราก็จัดการแก้โค้ดในส่วนของ else ให้ return เป็นข้อความซะ แล้วก็อาจจะเปลี่ยนชื่อฟังก์ชันเพื่อให้อ่านแล้วเข้าใจได้การทำงานได้ดีขึ้นอีกจาก “numberToAccounting” เป็น “numberToAccountingString”

function numberToAccountingString(number) {
   if (number < 0) {
      return '(' + Math.abs(number) + ')'
   } else if (number >= 0) {
      return number.toString()
   }
}
 
 
console.log(numberToAccountingString(-5))
console.log(typeof numberToAccountingString(-5))
console.log(numberToAccountingString(10))
console.log(typeof numberToAccountingString(10))

คราวนี้ผลลัพธ์ก็จะเป็น String ไม่ว่าจะเข้าเงื่อนไขไหนก็ตาม

(5)
string
10
string

ลดการทำงานที่ไม่จำเป็น

หลายครั้งฟังก์ชันที่ทำงานซับซ้อนมีการเช็คเงื่อนไขมากมาย ก็ไม่สามารถทำงานได้เพียงเพราะพารามิเตอร์ที่ส่งเข้ามาไม่ถูกต้อง ซึ่งถ้าเรารู้อยู่แล้วว่ามีกรณีแบบไหนที่ฟังก์ชันของเราจะทำงานไม่ได้หรือไม่ต้องการให้ทำงาน เราก็ควรจัดเขียนเงื่อนไขเช็คตั้งแต่เริ่มเข้าฟังก์ชันซะก่อน อย่างในฟังก์ชัน numberToAccountingString ถ้าค่าที่รับเข้ามาไม่ใช่ตัวเลขก็จะเกิด error ได้แบบนี้

function numberToAccountingString(number) {
   if (number < 0) {
      return '(' + Math.abs(number) + ')'
   } else if (number >= 0) {
      return number.toString()
   }
}
 
console.log(numberToAccountingString(null))

ผลลัพธ์

error: Uncaught TypeError: Cannot read property 'toString' of null

จะเห็นว่ากว่าจะเกิด error ขึ้นในบรรทัดที่แปลง number ไปเป็น string ฟังก์ชันของเราก็ทำงานไปหลายบรรทัดแล้ว ซึ่งในกรณีแบบนี้เราสามารถให้หยุดการทำงานตั้งแต่เข้ามาในฟังก์ชันได้เลย ด้วยการสร้าง Guard Clause ขึ้นมาเช็คแบบโค้ดด้านล่างนี้

function numberToAccountingString(number) {
   if (number == null || !number.isNumeric()) return
   if (number < 0) {
      return '(' + Math.abs(number) + ')'
   } else if (number >= 0) {
      return number.toString()
   }
}
 
console.log(numberToAccountingString(null))

ในโค้ดนี้ยังมีสิ่งที่หลายๆคนมองข้ามไปในตอนที่เขียนโค้ดก็คือการเช็คเงื่อนไข จะเห็นว่าฟังก์ชันของเรามีการทำงาน 2 แบบก็คือกรณีที่ number น้อยกว่า 0 และกรณีที่ number มีค่าเป็น 0 ขึ้นไป ซึ่งในโค้ดเราเช็คใน if ว่า

if (number < 0)

โค้ดตรงนี้ก็ครอบคลุมในกรณีแรกครบแล้ว กรณีที่ไม่เข้าเงื่อนไขนี้ก็หมายความว่าจะเป็นกรณีที่ number เป็น 0 มากกว่า 0 แน่นอน แต่ในโค้ดของเราก็ยังเขียนเพื่อเช็คอีกรอบอยู่

else if (number >= 0)

ซึ่งเป็นโค้ดที่ไม่จำเป็น เราสามารถตัดออกไปได้โดยที่ฟังก์ชันยังทำงานได้เหมือนเดิม แถมยังลดความ’เยอะ’หรือ’ซับซ้อน’ของโค้ดโดยรวมลงได้

function numberToAccountingString(number){
   if (number == null || !number.isNumeric()) return
   if (number < 0) {
      return '(' + Math.abs(number) + ')'
   } else {
      return number.toString()
   }
}

ไม่ใช้ตัวแปรเดียวสำหรับทำทุกอย่าง

ในการเขียนโค้ดที่ต้องทำงานหลายขั้นตอนเพื่อให้ได้ผลลัพธ์ออกมา การสร้างตัวแปรเพื่อใช้ภายในฟังก์ชันก็เป็นสิ่งสำคัญที่อาจถูกมองข้าม ลองดูจากโค้ดคำนวนราคาด้านล่างนี้

const TAX_RATE = 1.1
const SHIPPING_DEFAULT = 5
 
function calculateTotal(items, options = {}) {
   if (items == null || items.lenght === 0) return 0
 
   let total = 0
   items.forEach(item => {
      total += item.price * item.quantity
   })

   total = total - total * (options.discount || 0)
   total = total * TAX_RATE

   if (options.shipping !== 0) {
      total = total + (options.shipping || SHIPPING_DEFAULT)
   }

   return total
}
 
const testItem = [
   { price: 15, quantity: 2 },
   { price: 20, quantity: 1 },
   { price: 5, quantity: 4 }
]
 
console.log(calculateTotal(testItem, {}))
console.log(calculateTotal(testItem, { shipping: 0 }))
console.log(calculateTotal(testItem, { discount: .75 }))
console.log(calculateTotal(testItem, { shipping: 12 }))

ผลลัพธ์

82
77
24.25
89

ตัวแปร total ในฟังก์ชันนั้นถูกสร้างมาตั้งแต่เข้าฟังก์ชันและใช้การอัพเดตค่าในตัวแปรเพื่อเก็บราคารวม ราคาที่คำนวนส่วนลด และราคาหลังคิดภาษี ซึ่งได้ผลลัพธ์การทำงานถูกต้อง แต่ว่าถ้าเราย้อนกลับมาแก้ไขฟังก์ชันนี้ในอนาคต หรือถ้าหากว่าฟังก์ชันนี้มีการทำงานที่ยาวเป็นร้อยบรรทัด การที่เราจะแก้ไขบางอย่างกับตัวแปร total ก็อาจจะกระทบทั้งฟังก์ชันเลยก็ได้ เราจึงควรสร้างตัวแปรเพื่อใช้เก็บข้อมูลหรือผลลัพธ์ให้ตรงกับการทำงาน อย่างโค้ดคำนวนราคาก็จะได้ออกมาเป็น

const TAX_RATE = 1.1
const SHIPPING_DEFAULT = 5
 
function calculateTotal(items, options = {}) {
   if (items == null || items.lenght === 0) return 0
 
   let itemCost = 0
   items.forEach(item => {
      itemCost += item.price * item.quantity
   })
 
   let discountRate = 1 - (options.discount || 0)
 
   let shipping = SHIPPING_DEFAULT
   if( options.shipping || options.shipping === 0) {
      shipping = options.shipping
   }
 
   return itemCost * discountRate * TAX_RATE + shipping
}
 
const testItem = [
   { price: 15, quantity: 2 },
   { price: 20, quantity: 1 },
   { price: 5, quantity: 4 }
]
 
console.log(calculateTotal(testItem, {}))
console.log(calculateTotal(testItem, { shipping: 0 }))
console.log(calculateTotal(testItem, { discount: .75 }))
console.log(calculateTotal(testItem, { shipping: 12 }))

ผลลัพธ์

82
77
24.25
89

จากวิธีต่างๆที่ยกตัวอย่างมาในครั้งนี้ก็เป็นส่วนเล็กๆที่เราสามารถนำไปปรับใช้กับการเขียน JavaScript ของเราได้ง่ายๆ บางข้ออาจจะเป็นเรื่องพื้นฐานอย่างการตั้งชื่อตัวแปร หรือบางข้อก็เป็นเรื่องเล็กๆน้อยๆอย่างชนิดข้อมูลที่รีเทิร์น แต่ว่าทั้งหมดนี้ถ้าเรานำไปใช้โค้ด JavaScript ของเราก็จะออกมาดูเหมือนมือโปรขึ้นเยอะ เพราะว่าสิ่งสำคัญในการเขียนโค้ดไม่ใช่การเขียนให้ทำงานได้ แต่เป็นการทำให้โค้ดแก้ไขง่ายและอ่านเข้าใจได้นั่นเองครับ

บทความนี้อ้างอิงเนื้อหาและโค้ดตัวอย่างจากวีดีโอด้านล่างนี้นะครับ ถ้าใครสนใจจะดูแบบเต็มๆอธิบายทีละบรรทัดละก็คลิกเข้าไปดูกันได้ เค้าอธิบายเอาไว้ได้ดีมากๆ

Develeper

Author Develeper

More posts by Develeper

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า