Skip to content
This page is a draft. It may be incomplete or contain inaccuracies. If you have any comment, please feel free to leave some feedback!

ตัวเลขและตัวดำเนินการ (Numbers and Operators)

มีแค่ไม่กี่คนที่ตอบถูก!

  • ถ้าคุณเคยไถเฟสบุ๊ก คุณอาจจะเคยเห็นโพสต์แบบนี้มาบ้าง:

    ตอบเท่าไหร่ ??
    10 + 10 × 0 + 10 = ?

    (a) 10 (b) 20 (c) 110 (d) 200

    มีคนเพียง 8% เท่านั้นที่ตอบถูก!

    แล้วในคอมเม้นต์ก็มีแต่คนมาเถียงกันไม่จบไม่สิ้นว่าตกลงคำตอบที่ถูกต้องคือเท่าไหร่

  • ซึ่งถ้าจะถามว่าตกลงคำตอบที่ถูกต้องมันคือเท่าไหร่ เราก็อาจจะยังฟันธงไม่ได้ซะทีเดียว เพราะคำถามนี้มันกำกวม (ambiguous) มันไม่ชัดเจนพอ มันไม่ได้ระบุเลยด้วยซ้ำ ว่าโจทย์นี้ควรจะตีความยังไง

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

  • ผมว่ามันก็ชัดเจนขึ้นนะ แต่ว่าก็ยังกำกวมอยู่ดี เพราะเครื่องคิดเลขมีหลายยี่ห้อ ถ้าใช้เครื่องคิดเลขบน macOS ก็จะได้คำตอบเป็น 20 แต่ถ้าใช้เครื่องคิดเลขบน Windows แบบเบสิค ก็จะได้คำตอบเป็น 10

  • หรือถ้าเราเปลี่ยนโจทย์เป็น ให้คำนวณคำตอบโดยอิงลำดับการดำเนินการตามกฏ PEMDAS ได้คำตอบเท่าไหร่ อันนี้ค่อนข้างชัดเจนครับ

    กฏ PEMDAS คือกฏการคำนวณที่เราเรียนกันในโรงเรียน ซึ่งระบุไว้ว่าให้ทำการคูณก่อนบวก กรณีนี้ก็จะได้คำตอบเป็น 20

  • ลองเปลี่ยนโจทย์ดูอีกสักรอบ ให้แปลงโจทย์เป็นภาษา JavaScript แล้วเอาไปรันใน Console ได้คำตอบเท่าไหร่ อันนี้ค่อนข้างชัดเจนเช่นกัน ถ้าทำตามก็จะได้คำตอบเป็น 20 ครับ

  • แต่ทำไมถึงได้ 20 ล่ะ? นี่คือสิ่งที่เราจะมาหาคำตอบกันในหัวข้อนี้ครับ

เอกซ์เพรสชัน (นิพจน์) และตัวดำเนินการ

  • ก่อนที่เราจะไปกันต่อ ผมอยากจะแนะนำให้รู้จักคำศัพท์ต่าง ที่สำคัญก่อนครับ

  • Expression (แปลเป็นภาษาไทยว่า “นิพจน์” คำว่า “พจน์” มีรากศัพท์มาจากคำว่า ‘วจน’ ที่แปลว่า ‘คำพูด’ หรือ ‘ถ้อยคำ’ ครับ)

    คำว่า Expression ในเชิงการเขียนโปรแกรม ความหมายของมันคือ “ชิ้นส่วนของโค้ดที่เราเขียน ที่สามารถนำมาหาค่า หรือ Value ได้”

    “An expression is a valid unit of code that resolves to a value
    — MDN. “Expressions and Operators.” JavaScript Guide.

  • อันนี้คือตัวอย่าง Expression อย่างง่ายครับ คือมีแค่ตัวเลขเดียว “ค่าของ 123 คือเท่าไหร่” คำตอบคือ 123 ครับ

  • เราสามารถสร้าง Expression ที่ซับซ้อนขึ้นได้ โดยการเอา Expression ที่ขนาดเล็กกว่ามาประกอบกัน โดยใช้สิ่งที่เรียกว่า Operator (หรือ ตัวดำเนินการ) เป็นตัวเชื่อมครับ “ค่าของ 123 * 456 คือเท่าไหร่” คำตอบคือ 56088 ครับ

    “complex expressions are joined by operators”
    — MDN. “Expressions and Operators.” JavaScript Guide.

  • ภาษา JavaScript มี Operator ให้เราเลือกใช้เยอะมาก แต่ในคอร์สนี้เราจะได้เรียนรู้แค่บางตัว

ลำดับการทำงานของตัวดำเนินการ (Operator precedence and associativity)

  • กลับมาที่โจทย์เดิิมกัน:

  • เรามีข้อมูลอยู่ 4 ชิ้น (แทนด้วย a, b, c, d ในรูปข้างล่าง)

    เราต้องการนำข้อมูลพวกนี้มาดำเนินการอะไรซักอย่าง (แทนด้วยวงกลมสามวงในรูปข้างล่าง)

    แต่เราควรจะทำอันไหนก่อน?

  • จะเห็นว่าในตัวอย่างนี้ เราสามารถจัดรูปแบบ (ใส่วงเล็บ) ให้มันได้ถึง 5 วิธีที่แตกต่างกัน ซึ่งแต่ละวิธีก็มีโอกาสที่จะได้คำตอบที่แตกต่างกันออกไป

  • อย่างเช่น 10 + 10 * 10 + 10 ถ้าเรายังไม่รู้เรื่องลำดับการทำงานของตัวดำเนินการ เราก็อาจจะใส่วงเล็บได้ 5 วิธีดังนี้ครับ:

    ตัวอย่างการใส่วงเล็บคำตอบ
    ((10 + 10) * 0) + 1010
    10 + (10 * (0 + 10))110
    (10 + (10 * 0)) + 1020
    10 + ((10 * 0) + 10)20
    (10 + 10) * (0 + 10)200

    แล้วการใส่วงเล็บแบบไหนล่ะ ที่ถูกต้อง?

  • แหล่งข้อมูลสำคัญ ที่จะช่วยให้เราหาคำตอบนี้ได้ก็คือ JavaScript Reference หรือ “เอกสารอ้างอิงภาษา JavaScript” ครับ

  • ในเอกสารนี้จะมีบทนึงที่พูดถึงสิ่งที่เรียกว่า Operator precedence หรือ “ลำดับการทำงานของตัวดำเนินการ” ครับ เลื่อนลงมาเราจะเจอกับตารางที่บอกลำดับการทำงานของ Operator แต่ละตัวครับ

    และในตารางนี้เอง ที่เราจะได้เห็นว่า การคูณ (*) มีลำดับความสำคัญที่สูงกว่าการบวก (+) ครับ

  • นั่นหมายความว่า ถ้าเรามีตัวดำเนินการคุณ กับตัวดำเนินการบวก เราจะจับกลุ่มให้ตัวดำเนินการคูณก่อนครับ

    js
    // โจทย์
    10 + 10 * 0 + 10
    // ⬇
    // ทำการคูณก่อนการบวก
    10 + (10 * 0) + 10
  • คราวนี้ เราเหลือของ 3 อย่าง มาบวกกันแล้ว แต่ทีนี้ เนื่องจากทั้ง Operator ด้านซ้ายเป็นการบวก และ Operator ด้านขวาก็เป็นการบวกด้วย แปลว่าทั้งสองตัวมีลำดับความสำคัญเท่ากัน

  • แต่ในตารางเดียวกันนี้ ก็ได้ระบุไว้ด้วยว่า เครื่องหมาย + จะมีสิ่งที่เรียกว่า associativity จากซ้ายไปขวา

  • นั่นแปลว่า ให้เราจับกลุ่มเครื่องหมาย + จากซ้ายไปขวาครับ

    js
    // บวกค่าด้านซ้ายก่อน แล้วค่อยไปบวกค่าด้านขวา
    (10 + (10 * 0)) + 10
    // ⬇
    (10 + 0) + 10
    // ⬇
    10 + 10
    // ⬇
    20
  • แค่นี้มันก็ไม่กำกวมแล้ว และเราสามารถคำนวณคำตอบได้เป็น 20 ครับ