φυβλαςのβλογ
phyblas的博客



javascript เบื้องต้น บทที่ ๑๗: ฟังก์ชันภายในตัว
เขียนเมื่อ 2019/07/31 23:28
แก้ไขล่าสุด 2021/09/28 16:42



ฟังก์ชันและออบเจ็กต์ในตัว

ในบทก่อนที่ผ่านมานี้ก็ได้แนะนำฟังก์ชันบางส่วนที่ในจาวาสคริปต์ให้มาตั้งแต่ต้น ที่ไม่ได้อยู่ในออบเจ็กต์ใดๆ สามารถใช้ได้ทันทีโดยตรง ได้แก่ alert parseInt parseFloat

ในบทนี้จะแนะนำฟังก์ชันส่วนที่เหลือในกลุ่มนี้

ที่จริงแล้วจาวาสคริปต์มีจำนวนฟังก์ชันแบบนี้ไม่มากนัก เพราะส่วนใหญ่จะใส่มารวมอยู่ในออบเจ็กต์เป็นหมวดๆ เช่น Object, Math, String, Number ดังที่ได้กล่าวไปแล้ว

ฟังก์ชันในกลุ่มนี้มีดังนี้

parseInt แปลงข้อมูลเป็นเลขจำนวนเต็ม
parseFloat แปลงข้อมูลเป็นเลขทศนิยมจุดลอย
encodeURI แปลงอักษรต้องห้ามใน URI เป็นโค้ด
encodeURIComponent แปลงอักษรต้องห้ามใน URI เป็นโค้ด
decodeURI แปลงโค้ดกลับเป็นอักษรใน URI
decodeURIComponent แปลงโค้ดกลับเป็นอักษรใน URI
eval รันโค้ดจาวาสคริปต์ในสายอักขระ
isFinite ตรวจดูว่าค่าไม่เป็นอนันต์หรือไม่ คืนค่า false เมื่อเจอ Infinity หรือสิ่งที่ไม่อาจแปลงเป็นตัวเลขได้
isNaN ตรวจดูว่าค่าเป็น NaN หรือไม่ คืนค่า true เมื่อเป็น NaN หรือสิ่งที่ไม่อาจแปลงเป็นตัวเลขได้

อย่างไรก็ตาม ใน ES6 ฟังก์ชัน parseInt, parseFloat, isFinite, isNaN ได้ถูกนำไปรวมในออบเจ็กต์ Number ด้วย เพราะเป็นฟังก์ชันที่เกี่ยวกับตัวเลข

ดังนั้น parseInt สามารถเขียนเป็น Number.parseInt และ parseFloat สามารถเขียนเป็น Number.parseFloat ได้ด้วย ผลที่ได้จะเหมือนกัน

แต่สำหรับ isFinite กับ isNaN นั้นจะต่างจาก Number.isFinite และ Number.isNaN เล็กน้อย รายละเอียดจะเขียนถึงต่อไป



ตรวจว่าจำนวนเป็น NaN หรือไม่ ด้วย isNaN

NaN คือข้อมูลชนิดตัวเลขแบบหนึ่งที่มีความหมายว่าไม่ใช่ตัวเลข เป็นอะไรบางอย่างที่ไม่อาจตีความเป็นตัวเลขได้ มักเกิดจากการคำนวณตัวเลขที่ไม่ควรจะคำนวณได้ เช่น
alert(Math.log(-1)); // ได้ NaN
alert(Math.asin(2)); // ได้ NaN

แต่แม้ว่าจะเป็น NaN เหมือนกัน เป็นจำนวนเดียวกัน แต่ NaN เทียบกันเองก็จะได้ false เท่านั้น
alert(NaN == NaN); // ได้ false
alert(Math.asin(2) == NaN); // ได้ false

ดังนั้น การจะตรวจสอบ NaN จึงจำเป็นต้องใช้ฟังก์ชัน isNaN ซึ่งจะให้ค่า true เมื่อเจอ NaN นอกนั้นเป็น false
alert(isNaN(NaN)); // ได้ true
alert(isNaN(Math.asin(2))); // ได้ true
alert(isNaN(1)); // ได้ false


ตรวจว่าจำนวนมีค่าจำกัดหรือไม่ด้วย isFinite

ในจาวาสคริปต์มีค่าที่เรียกว่า Infinity คือจำนวนอนันต์ อาจเกิดขึ้นมาเมื่อมีการคำนวณบางอย่าง เช่น 1/0 หรือเลขที่คำนวณแล้วมีค่ามากเกินขอบเขตสูงสุด

นอกจากนี้ยังมีค่าที่ตรงกันข้ามกับ infinity คือ -Infinity

ตัวอย่าง
alert(1/0); // ได้ Infinity
alert(-1/0); // ได้ -Infinity
alert(Math.log(0)); // ได้ -Infinity
alert(Math.pow(10, 1000)); // ได้ Infinity

isFinite เป็นฟังก์ชันที่ตรวจสอบว่าค่าตัวเลขนั้นเป็นจำนวนจำกัดหรือไม่ ถ้าค่าเป็น Infinity หรือ -Infinity หรือ NaN ก็จะได้ false
alert(isFinite(NaN)); // ได้ false
alert(isFinite(-Infinity)); // ได้ false
alert(isFinite(Math.pow(10, 100))); // ได้ true
alert(isFinite(Math.pow(10, 1000))); // ได้ false


ความแตกต่างระหว่าง isFinite isNan และ Number.isFinite Number.isNaN ใน ES6

ใน ES6 ได้มีการนำฟังก์ชัน isFinite และ isNaN มาใส่ในออบเจ็กต์ Number ความหมายคล้ายกับ isFinite และ isNaN เดิม แต่มีข้อแตกต่างเกิดขึ้นในการใช้งาน เมื่อใช้กับข้อมูลที่ไม่ใช่ตัวเลข

สำหรับ isFinite หากใส่ข้อมูลที่ไม่ใช่ชนิดตัวเลขมาจะถูกพยายามแปลงเป็นตัวเลข ถ้าแปลงแล้วเป็นตัวเลขก็จะได้ true อยู่ แต่ Number.isFinite นั้นถ้าใส่ข้อมูลที่ไม่ใช่ชนิดตัวเลขจะได้ false ตลอด ไม่มีการแปลงให้
alert(isFinite("0")); // ได้ true
alert(Number.isFinite("0")); // ได้ false

ส่วน isNaN นั้นถ้าใส่ข้อมูลที่ไม่ใช่ตัวเลขจะถูกพยายามแปลงเป็นตัวเลข ถ้าเป็นตัวที่แปลงไม่ได้จึงจะได้ true แต่สำหรับ Number.NaN นั้นจะได้ false เสมอ
alert(isNaN("0")); // ได้ false
alert(isNaN("ความรัก")); // ได้ true
alert(Number.isNaN("0")); // ได้ false
alert(Number.isNaN("ความรัก")); // ได้ false


การแปลง uri เป็นโค้ด

uri (uniform resource identifier) แปลตรงๆก็คือ "ตัวระบุแหล่งทรัพยากรสากล" หรืออธิบายด้วยคำที่เข้าใจง่ายขึ้นหน่อยก็คือเป็น "ชื่อที่ใช้ระบุตัวตนของไฟล์"

uri ที่คนส่วนใหญ่รู้จักกันดีก็คือ url (uniform resource location) ซึ่งก็คือที่อยู่ของเว็บนั่นเอง ที่จริง url ก็เป็น uri ชนิดหนึ่ง

ปกติเวลาเราพิมพ์ url เพื่อเข้าเว็บจะพบว่ามีบางตัวถูกแปลงเป็นรหัสซึ่งประกอบด้วย % ตามด้วยเลขฐานสิบหกสองหลัก

ฟังก์ชัน encodeURI และ encodeURIComponent เป็นฟังก์ชันที่ช่วยแปลงสัญลักษณ์เหล่านี้ให้เป็นรหัส

ข้อแตกต่างคือ encodeURIComponent จะมีอักษรที่แปลงมากกว่า encodeURI

สัญลักษณ์ที่ไม่มีการแปลงได้แก่ ! ( ) - * ~ _ . '

นอกจากนี้ตัวเลข 0 ถึง 9 อักษร a ถึง z ทั้งพิมพ์เล็กและพิมพ์ใหญ่ก็จะไม่มีการแปลง

อักษรที่ถูกแปลงเมื่อใช้ encodeURIComponent แต่ไม่แปลงเมื่อใช้ encodeURI ได้แก่

ชื่อเรียก สัญลักษณ์ รหัส
แฮช # %23
ดอลลาร์ $ %24
บวก + %2B
ทับ (สแลช) / %2F
แอต @ %40
อัฒภาค (เซมิโคลอน) ; %3B
ทวิภาค (โคลอน) : %3A
จุลภาค , %2C
แอนด์ (แอมเพอร์แซนด์) & %26
เท่ากับ = %3D
ปรัศนี (เครื่องหมายคำถาม) ? %3F

สัญลักษณ์และอักษรนอกเหนือจากที่กล่าวมานี้ เช่น % \ " | จะถูกแปลงทั้งหมด

ตัวอย่าง
var url = "https://th.wikipedia.org/wiki/ยูอาร์แอล#อ้างอิง";
alert(encodeURIComponent(url) + "\n" + encodeURI(url));
ได้
https%3A%2F%2Fth.wikipedia.org%2Fwiki%2F%E0%B8%A2%E0%B8%B9%E0%B8%AD%E0%B8%B2%E0%B8%A3%E0%B9%8C%E0%B9%81%E0%B8%AD%E0%B8%A5%23%E0%B8%AD%E0%B9%89%E0%B8%B2%E0%B8%87%E0%B8%AD%E0%B8%B4%E0%B8%87
https://th.wikipedia.org/wiki/%E0%B8%A2%E0%B8%B9%E0%B8%AD%E0%B8%B2%E0%B8%A3%E0%B9%8C%E0%B9%81%E0%B8%AD%E0%B8%A5#%E0%B8%AD%E0%B9%89%E0%B8%B2%E0%B8%87%E0%B8%AD%E0%B8%B4%E0%B8%87

ในทางกลับกันมีฟังก์ชัน decodeURI และ decodeURIComponent ไว้ใช้สำหรับแปลงกลับ
alert(decodeURI("%E0%B8%A3%E0%B8%B1%E0%B8%81")); // ได้ รัก
alert(decodeURI("%40_%40")); // ได้ %40_%40
alert(decodeURIComponent("%40_%40")); // ได้ @_@


การใช้ eval

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

ตัวอย่าง
eval('var e = "eval"\nalert("ฉันชื่อ " + e + " 我叫"+ e)'); // ได้ ฉันชื่อ eval 我叫eval

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

มีบางสถานการณ์ที่ใช้ eval แล้วเหมือนจะสะดวก แต่หากมีวิธีเลี่ยงไปใช้วิธีอื่นได้ก็ควรจะใช้มากกว่า




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

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

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

หมวดหมู่

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

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

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



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

  查看日志

  推荐日志

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