φυβλαςのβλογ
บล็อกของ phyblas



javascript เบื้องต้น บทที่ ๔: นิพจน์และการคำนวณ
เขียนเมื่อ 2019/07/31 23:08
แก้ไขล่าสุด 2021/09/28 16:42


ตัวดำเนินการพื้นฐาน

หลังจากที่ได้แนะนำให้รู้จักชนิดข้อมูลต่างๆไปแล้ว ในบทนี้จะมาพูดถึงการนำข้อมูลมาดำเนินการทำอะไรกัน

อย่างที่เห็นในตัวอย่างก่อนๆไปแล้วว่าข้อมูลชนิดตัวเลขสามารถนำมาบวกกันได้ เช่น 1+2

ในกรณีเครื่องหมายสัญลักษณ์บวก + เรียกว่าเป็น "ตัวดำเนินการ" (operator) และการที่ตัวเลขหรือตัวแปรมาทำอะไรบางอย่างกันนี้เรียกว่า "นิพจน์" (expression)

สัญลักษณ์ต่างๆที่ใช้แทนตัวดำเนินการในนิพจน์ที่มักพบในทุกภาษาในความหมายเหมือนกันไม่ว่าจะในภาษาไหนก็คือ +, -, *, /, %
  • x + y บวก
  • x - y ลบ
  • x * y คูณ
  • x / y หาร
  • x % y หารเอาเศษ
ตัวอย่าง
alert(33 + 44); // ได้ 77
alert(44 - 33); // ได้ 11
alert(11 * 4); // ได้ 44
alert(44 / 4); // ได้ 11
alert(55 % 10); // ได้ 5

นอกจากนี้ตั้งแต่รุ่น ES2016 จึงได้มีตัวดำเนินการใหม่เพิ่มเข้ามาคือ ** เอาไว้ใช้แทนเลขยกกำลัง

x ** y คือ x ยกกำลัง y

ตัวดำเนินการ ** นั้นถูกใช้ในภาษาอื่นหลายภาษา แต่ในจาวาสคริปต์เพิ่งใส่เพิ่มเข้ามา จึงเริ่มใช้ได้

ถ้าหากเป็นรุ่นก่อนหน้านี้เวลาจะต้องเขียน Math.pow(x,y) เมื่อต้องการคำนวณ x ยกกำลัง y



ตัวดำเนินการแบบเปลี่ยนแปลงค่าตัวแปรเดิม

ตัวดำเนินการที่กล่าวมาข้างต้นได้แก่ +-*/% นั้นจะทำการคำนวณแล้วคืนค่าใหม่มาให้ ไม่ได้เกิดอะไรขึ้นกับตัวแปรเดิมที่ใส่เข้าไป

หากเติมเครื่องหมาย = เข้าไปจะหมายถึงให้ทำการดำเนินการด้วยค่าตัวแปรเดิมของตัวนั้นกับค่าที่ใส่เข้าไปด้านหลัง
  • x += y เท่ากับ x = x + y
  • x -= y เท่ากับ x = x - y
  • x *= y เท่ากับ x = x * y
  • x /= y เท่ากับ x = x / y
  • x %= y เท่ากับ x = x % y
ตัวอย่าง
var x = 8;
x += 2;
alert(x); // ได้ 10

นอกจากนี้สำหรับเครื่องหมายบวกและลบหากเขียนสองตัวต่อกันจะหมายถึงการเอาตัวแปรนั้นมาบวก 1 หรือลบ 1
  • x++
  • x--
  • ++x
  • --x
การเอาเครื่องหมายไว้ด้านหน้าและด้านหลังมีความหมายต่างกันเล็กน้อย ความแตกต่างจะเห็นในกรณีที่เอาค่านี้ไปแทนใส่ตัวแปรอื่นด้วยในทีเดียว
var y1 = 5;
z1 = y1++;
alert(z1); // ได้ 5
alert(y1); // ได้ 6

var y2 = 5;
z2 = ++y2;
alert(z2); // ได้ 6
alert(y2); // ได้ 6

จะเห็นว่าถ้าวาง ++ ไว้ด้านหลัง การบวกเพิ่มจะเกิดขึ้นหลังจากที่ค่าแทนเข้าไปในตัวแปรทางซ้ายแล้ว แต่ถ้าอยู่ด้านหน้าก็จะเกิดการบวกทันทีแล้วจึงแทนในตัวแปรซ้ายไปด้วย

แต่โดยส่วนมาก ++ จะใช้ในกรณีที่ต้องการเพิ่มค่าตัวแปรไปอีก 1 โดยเขียนแบบง่ายๆว่า
++x;
x++;

ถ้าจุดประสงค์แค่ต้องการเพิ่มค่า x แบบนี้จะเขียนแบบไหนก็ไม่ต่างกัน ความหมายล้วนหมายถึงค่าของ x บวกเพิ่มอีก 1 เหมือนกัน



ขีดจำกัดของค่าตัวเลข และค่าอนันต์

การคำนวณในคอมพิวเตอร์นั้นมีข้อจำกัด ไม่สามารถป้อนค่าตัวเลขที่ใหญ่เกินค่าค่าหนึ่งได้

ค่าที่ใหญ่เกินก็จะกลายเป็น Infinity คือค่าอนันต์ นอกจากนี้อาจเกิดจากการคำนวณบางอย่าง เช่นหารด้วย 0 เช่น
alert(1e400); // ได้ Infinity
alert(-1 / 0); // ได้ -Infinity

ค่าสูงสุดของตัวเลขที่สามารถเก็บในโปรแกรมได้สามารถดูได้ที่ Number.MAX_VALUE ถ้าเกินกว่าค่านี้ไปก็จะกลายเป็น Infinity
alert(Number.MAX_VALUE); // ได้ 1.7976931348623157e+308
alert(1.8e308); // Infinity

ในทางกลับกัน จำนวนที่มีค่าเล็กจนเข้าใกล้ 0 มากๆก็มีขีดจำกัดเช่นกัน ดูได้ที่ค่า Number.MIN_VALUE หากใส่ค่าที่น้อยกว่านี้ไปก็จะกลายเป็น 0
alert(Number.MIN_VALUE); // ได้ 5e-324
alert(2.5e-324); // ได้ 5e-324
alert(2.4e-324); // ได้ 0

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



ลำดับความสำคัญในการคำนวณ

เวลาที่มีนิพจน์ยาวๆซึ่งประกอบด้วยสัญลักษณ์ในการคำนวณหลายตัว การคำนวณจะเกิดขึ้นต่อเนื่องหลายครั้งซ้อนกันไปเรื่อยๆ โดยเริ่มไล่จากซ้ายไปขวา เช่น
var a = 1 + 2 + 3 - 4;

การคำนวณจะเริ่มต้นจาก 1 บวก 2 แล้วค่อยไปบวก 3 แล้วลบ 4 ตามลำดับ

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

แต่ถ้าลองเขียนแบบนี้
var a = 2 * 3 + 4 / 5;
alert(a); // ได้ 6.8

จะพบว่าโปรแกรมจะคำนวณโดยเอา 2 คูณ 3 แล้วก็เอา 4 หาร 5 แล้วค่อยเอาทั้งสองส่วนนี้มาบวกกัน

นั่นเพราะลำดับความสำคัญของเครื่องหมายคูณและหารนั้นมาก่อนบวกกับลบ ดังนั้นเมื่อเห็น 4/5 จึงถูกคิดก่อนเครื่องหมายบวกที่อยู่ทางซ้าย

หากต้องการเปลี่ยนลำดับความสำคัญก็สามารถทำได้โดยใส่วงเล็บ
var a = (2 * 3) + (4 / 5); // อันนี้ใส่หรือไม่ก็เหมือนกัน
alert(a); // ได้ 6.8
var a = (2 * 3 + 4) / 5;
alert(a); // ได้ 2
var a = ((2 * 3) + 4) / 5;
alert(a); // ได้ 2

จะเห็นว่า 2*3 จะใส่วงเล็บหรือไม่ใส่ก็ไม่ต่างกัน เพราะความสำคัญของคูณมาก่อนบวกอยู่แล้ว

หากเรียงความสำคัญก็จะได้ดังนี้

- วงเล็บ ()
- คูณ (*) หาร (/) หารเอาเศษ (%)
- บวก (+) ลบ (-)

ถ้าลำดับความสำคัญเท่ากันก็จะคิดจากซ้ายไปขวา



การคำนวณของ true และ false

true false สามารถนำมาใช้ในการคำนวณบวกลบคูณหารได้ โดยเวลาคำนวณจะถูกแปลงข้อมูลเป็นตัวเลขโดยอัตโนมัติ true จะมีค่าเป็น 1 และ false มีค่าเป็น 0

สามารถนำ true false มาเข้านิพจน์คำนวณกันเองก็ได้ หรือจะทำกับตัวเลขก็ได้
alert(true + true); // ได้ 2
alert(true + false); // ได้ 1
alert(true * true); // ได้ 1
alert(true * false); // ได้ 0
alert(true + 7); // ได้ 8
alert(8 * false); // ได้ 0

แต่ยกเว้นกรณีที่ไปบวกกับข้อมูลชนิดสายอักขระ กรณีนั้นจะถูกเปลี่ยนเป็นสายอักขระแทน ตัวอย่างจะกล่าวถึงต่อไป



การบวกสายอักขระ

หากนำสายอักขระมาบวกกันจะเป็นการนำสายอักขระมาต่อกัน
alert("อา" + "ม่า"); // ได้ อาม่า

ต่อให้เป็นสายอักขระที่บรรจุแต่ตัวเลข เวลาที่บวกกันก็เป็นการเอามาต่อกันเช่นกัน ไม่ใช่การบวกตัวเลข
alert("11"+"22"); // ได้ 1122

หากมีตัวแปรที่เก็บสายอักขระอยู่ เราสามารถต่อข้อความเพิ่มลงสายอักขระได้โดยใช้ +=
var s = "เธอเป็นคนดี";
s += "แต่พูด";
alert(s); // ได้ เธอเป็นคนดีแต่พูด


การนำข้อมูลต่างชนิดกันมาเข้าตัวดำเนินการกัน

หากนำตัวเลขมาบวกกับสายอักขระ ตัวเลขจะถูกแปลงเป็นสายอักขระก่อนแล้วจึงบวกกัน นั่นหมายถึงกลายเป็นการเขียนต่อสายอักขระ
alert("1" + 2); // ได้ 12

เมื่อเกิดการบวกกับสายอักขระก็จะกลายเป็นสายอักขระทันที บวกกับอะไรต่อก็ได้แต่สายอักขระแล้ว ดังนั้นถ้าต้องการให้ตัวเลขบวกแบบคณิตศาสตร์ก็ต้องบวกกันก่อนแล้วค่อยเอามาต่อกับสายอักขระ
alert("a" + 2 + 4); // ได้ a24
alert("a" + (2 + 4)); // ได้ a6
alert(2 + 4 + "a"); // ได้ 6a

ถ้าสายอักขระบวกกับ true หรือ false ก็จะแปลงคำว่า true หรือ false เป็นสายอักขระโดยตรงแล้วก็ต่อกันไปแบบนั้น

alert("a" + true); // ได้ atrue

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

ถ้าสายอักขระนั้นบรรจะตัวเลข ก็จะถูกแปลงเป็นเลข แต่ถ้าไม่ใช่ตัวเลขก็จะได้ค่าเป็น NaN
alert("a" / 2); // ได้ NaN
alert("2" * 3); // ได้ 6
alert(2 - "9"); // ได้ -7

NaN ย่อมาจาก not a number แปลว่า "ไม่ใช่ตัวเลข" ถือเป็นข้อมูลชนิดตัวเลขชนิดหนึ่ง จะเกิดขึ้นเวลาเกิดการคำนวณแล้วไม่สามารถกลายเป็นตัวเลขได้

NaN เอาไปคำนวณอะไรต่อก็จะได้ NaN แต่ถ้าบวกกับสายอักขระจึงจะกลายเป็นการต่อกับสายอักขระ
alert(typeof NaN); // ได้ number
alert(NaN + 1); // ได้ NaN
alert(1 / NaN); // ได้ NaN
alert(NaN - "aNa"); // ได้ NaN
alert(NaN + "aNa"); // ได้ NaNaNa

สายอักขระเจอ true และ false ก็ถูกแปลงเป็นตัวเลขเช่นกัน
alert("-1" / false); // ได้ -Infinity
alert("a" * false); // ได้ NaN
alert("6" - true); // ได้ 5


กรณี undefined และ null

สำหรับ undefined นั้นไปคำนวณกับอะไรก็จะได้ NaN แต่ถ้าเป็นบวก เมื่อบวกกับสายอักขระจะแปลงเป็นสายอักขระแล้วนำไปต่อกัน

ส่วน null จะให้ผลเหมือน false

alert(undefined + "นะ"); // ได้ undefinedนะ
alert(undefined - "ล่ะ"); // ได้ NaN
alert(undefined * 10); // ได้ NaN
alert(undefined + true); // ได้ NaN
alert(null + "ล่ะ"); // ได้ nullล่ะ
alert(null - "ล่ะ"); // ได้ NaN
alert(null + 10); // ได้ 10
alert(null - "7"); // ได้ -7
alert(null * true); // ได้ 0

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




-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> javascript

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

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文