ฟังก์ชันและออบเจ็กต์ในตัว
ในบทก่อนที่ผ่านมานี้ก็ได้แนะนำฟังก์ชันบางส่วนที่ในจาวาสคริปต์ให้มาตั้งแต่ต้น
ที่ไม่ได้อยู่ในออบเจ็กต์ใดๆ สามารถใช้ได้ทันทีโดยตรง ได้แก่ 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 แล้วเหมือนจะสะดวก
แต่หากมีวิธีเลี่ยงไปใช้วิธีอื่นได้ก็ควรจะใช้มากกว่า