การเรียนรู้ภาษาการเขียนโปรแกรมมีเพียงสองด้านเท่านั้น: หนึ่งคือไวยากรณ์และอื่น ๆ คือประเภทข้อมูล ไวยากรณ์ของภาษาที่มีลักษณะเหมือน C นั้นไม่มีอะไรมากไปกว่าในขณะที่สำหรับฟังก์ชั่นการดำเนินการทางคณิตศาสตร์ ฯลฯ และภาษาที่มุ่งเน้นวัตถุจะถูกเพิ่มเข้าไปในวัตถุ
ไวยากรณ์เป็นเพียงชุดของกฎที่นักออกแบบภาษาทำล่วงหน้า ไวยากรณ์ของภาษาต่าง ๆ นั้นแตกต่างกัน แต่พวกเขาทั้งหมดมีบางจุดทั่วไป สำหรับผู้ที่คุ้นเคยกับภาษาการเขียนโปรแกรมหนึ่งหรือสองภาษาไวยากรณ์มักจะไม่เป็นปัญหาเมื่อเรียนรู้ภาษาการเขียนโปรแกรมอื่น ๆ (แน่นอนถ้าคุณได้เรียนรู้ภาษาที่เหมือน C แล้วมันจะต้องใช้เวลาพอสมควรในการมีส่วนร่วมใน LISP เป็นครั้งแรก) จุดเน้นของการเรียนรู้มักจะอยู่ในประเภทข้อมูลและการดำเนินการที่เกี่ยวข้องและไม่มีคำพูดเก่า ๆ : "โครงสร้างข้อมูล + อัลกอริทึม = โปรแกรม"! ประการที่สองไวยากรณ์ของบางภาษานั้นมีปัญหาในการออกแบบ (JavaScript มีมากขึ้น) ดังนั้นเราไม่จำเป็นต้องขุดลงไปในจุดเหล่านี้ แน่นอนถ้าคุณอ้างว่าเป็นคนขี้เกียจคุณสามารถเล่นกับมันได้
บทความนี้จะให้คำแนะนำรายละเอียดเกี่ยวกับประเภทข้อมูลใน JavaScript
ประเภทที่อ่อนแอเทียบกับประเภทที่แข็งแกร่ง
ด้วยปรัชญาการออกแบบของ JavaScript JavaScript ได้รับการออกแบบเป็นภาษาที่อ่อนแอ
การพูดถึงสิ่งนี้เป็นเรื่องที่หลีกเลี่ยงไม่ได้ที่จะพูดคุยเกี่ยวกับความแตกต่างระหว่างประเภทที่อ่อนแอและประเภทที่แข็งแกร่ง
บางคนคิดผิดพลาดว่าความแตกต่างระหว่างทั้งสองคือ "ภาษาที่พิมพ์อย่างยิ่งต้องระบุประเภทของมันเมื่อประกาศตัวแปรในขณะที่คนที่พิมพ์อย่างอ่อนแอไม่ได้ใช้" ในความเป็นจริงมุมมองนี้ผิด ตัวอย่างเช่นตัวอย่างรหัส Java ต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
สตริง s = "สวัสดี";
int l = s.getBytes (). ความยาว;
คอมไพเลอร์รู้ได้อย่างไรว่า. ความยาวเป็นนิพจน์ทางกฎหมาย? นี่เป็นเพราะคอมไพเลอร์รู้ว่าชนิดข้อมูลของ S คือสตริง เมื่อเรียกใช้วิธีการของสตริง GetBytes ประเภทข้อมูลของค่าส่งคืนคือไบต์ [] ดังนั้น. ความยาวเป็นนิพจน์ทางกฎหมาย
ความแตกต่างที่แท้จริงระหว่างทั้งสองคือ:
ในภาษาที่พิมพ์อย่างมากประเภทของแต่ละนิพจน์สามารถกำหนดได้ในเวลาคอมไพล์และการดำเนินการที่ใช้กับประเภทนั้นเท่านั้น
ภาษาประเภทที่อ่อนแออนุญาตให้มีการดำเนินการใด ๆ ในทุกประเภท แต่การดำเนินการนี้อาจรายงานข้อผิดพลาดที่รันไทม์
ชนิดข้อมูล
ตามข้อกำหนดของ ECMAScript 5.1 มีหกประเภทข้อมูลใน JavaScript คือ: undefined, null, boolean, จำนวน, สตริงและวัตถุ ห้าประเภทแรกเป็นของประเภทพื้นฐานและเป็นประเภทของวัตถุ
ชนิดข้อมูลพื้นฐาน
ประเภทที่ไม่ได้กำหนดมีค่าเดียวเท่านั้นซึ่งไม่ได้กำหนดซึ่งหมายถึง "ค่า NULL" ซึ่งใช้กับทุกประเภทข้อมูล
ประเภท null มีค่าเดียวเท่านั้นซึ่งเป็นโมฆะซึ่งหมายถึง "ไม่มีวัตถุ" และใช้กับประเภทวัตถุเท่านั้น
ประเภทบูลีนมีสองค่าจริงและเท็จ
ค่าของหมายเลขประเภทคือชุดของหมายเลขลอย 64 บิตที่เป็นไปตามมาตรฐาน IEEE 754 คล้ายกับ Double ของ Java ไม่มีโครงสร้างข้อมูลจำนวนเต็ม นอกจากนี้ยังมีสามค่าพิเศษ: Nan, Infinity, -infinity
ค่าของประเภทสตริงคือคอลเลกชันของอักขระ Unicode ที่ จำกัด ต้องปิดล้อมด้วย 'หรือ'
เป็นโมฆะและไม่ได้กำหนด
ทั้ง NULL และ Undefined แสดงถึงแนวคิดของ "ไม่ใช่ค่า" หากมีความโดดเด่นอย่างเคร่งครัด:
- null หมายถึงว่างเปล่า
- ไม่ได้กำหนดหมายความว่าไม่มีอยู่จริง ค่านี้เป็นตัวแปรทั้งหมดที่ไม่มีการเริ่มต้นพารามิเตอร์ที่ขาดหายไปในฟังก์ชันและไม่มีค่าคืนที่ชัดเจน
ในภาษาอื่น ๆ มีเพียงหนึ่งโมฆะที่ใช้เพื่อแสดงค่า NULL เหตุใดจึงไม่มีการกำหนดในจาวาสคริปต์? สิ่งนี้เกิดจากเหตุผลทางประวัติศาสตร์:
JavaScript ใช้ไวยากรณ์ Java แบ่งประเภทออกเป็นประเภทพื้นฐานและประเภทวัตถุ ใน Java, Null ใช้เพื่อเป็นตัวแทนของวัตถุที่ว่างเปล่าและ JavaScript สืบทอดพวกเขาเพื่อให้ได้รับ; ในภาษา C null คือ 0 เมื่อแปลงเป็นตัวเลขและ JavaScript ก็ใช้วิธีเดียวกัน:
การคัดลอกรหัสมีดังนี้:
> หมายเลข (NULL)
0
> 5 + null
5
ใน JavaScript 1.0 ยังไม่มีการจัดการข้อยกเว้น สำหรับข้อยกเว้นบางอย่าง (ไม่มีตัวแปรที่เริ่มต้นพารามิเตอร์ที่ขาดหายไปเมื่อเรียกใช้ฟังก์ชั่นการโทร ฯลฯ ) พวกเขาจะต้องทำเครื่องหมายเป็นค่าพิเศษ Null เป็นตัวเลือกที่ดี แต่ Brendan Eich ต้องการหลีกเลี่ยงสองสิ่งต่อไปนี้:
- ค่าพิเศษนี้ไม่ควรมีแอตทริบิวต์อ้างอิงเนื่องจากเป็นวัตถุเฉพาะ
- ค่าพิเศษนี้ไม่ควรแปลงเป็น 0 เพราะมันไม่ง่ายที่จะตรวจจับข้อผิดพลาดในโปรแกรม
ด้วยเหตุผลทั้งสองนี้เบรนแดนไอชเลือกที่ไม่ได้กำหนดซึ่งสามารถบังคับให้น่านได้
การคัดลอกรหัสมีดังนี้:
> หมายเลข (ไม่ได้กำหนด)
น่าน
> 5 + ไม่ได้กำหนด
น่าน
ผลลัพธ์จะแตกต่างกันมากเมื่อจัดการกับวัตถุ JSON:
การคัดลอกรหัสมีดังนี้:
> json.parse (Null)
โมฆะ
> json.parse (ไม่ได้กำหนด)
// firfox syntaxerror: json.parse: อักขระที่ไม่คาดคิดที่บรรทัด 1 คอลัมน์ 1 ของข้อมูล JSON
// Chrome SyntaxError: Token U ที่ไม่คาดคิด
> json.stringify (null)
"โมฆะ"
> json.stringify (ไม่ได้กำหนด)
ไม่ได้กำหนด
ประเภทวัตถุ
ในฐานะที่เป็นภาษาสคริปต์ JavaScript นั้นมีฟังก์ชั่นที่มีความคล่องตัวมากและฟังก์ชั่นมากมาย (การอ่านไฟล์และการเขียนเครือข่าย ฯลฯ ) จัดทำโดยสภาพแวดล้อมโฮสต์ สะพานเชื่อมระหว่างสภาพแวดล้อมโฮสต์และภาษาจาวาสคริปต์เป็นวัตถุ สภาพแวดล้อมโฮสต์มีฟังก์ชั่นที่หลากหลายโดยการจัดหาชุดของวัตถุที่สอดคล้องกับไวยากรณ์ JavaScript
ในบทความนี้ในการเขียนโปรแกรมเชิงวัตถุ JavaScript (ถ้าคุณไม่รู้ว่าต้นแบบคืออะไรฉันขอแนะนำอย่างยิ่งให้อ่านบทความนี้) ฉันได้เน้นซ้ำ ๆ ว่าวัตถุเป็นชุดของคู่คีย์-ค่าในจาวาสคริปต์เช่น HashMap ใน Java อย่างไรก็ตามคุณสมบัติของวัตถุใน JavaScript สามารถมีตัวอธิบายบางอย่าง (ตัวอธิบายคุณสมบัติ) ซึ่งไม่สามารถใช้ได้ใน HashMap
ตัวบ่งชี้แอตทริบิวต์
ตัวอธิบายแอตทริบิวต์แบ่งออกเป็นสองประเภท:
Data Descriptor (Data Descriptor) มีชุดของค่าบูลีนเพื่อระบุว่าแอตทริบิวต์อนุญาตให้มีการปรับเปลี่ยนและการลบหรือไม่
ตัวอธิบาย accessor รวมถึงฟังก์ชั่นรับและตั้งค่า
ตัวอธิบายทั้งสองเป็นวัตถุและพวกเขาทั้งสองมีคุณสมบัติบูลีนสองตัวต่อไปนี้:
สามารถกำหนดค่าได้เพื่อระบุว่า descriptor อนุญาตให้มีการแก้ไขและการลบหรือไม่ ค่าเริ่มต้นเป็นเท็จ
Enumerable ใช้เพื่อระบุว่าจะเข้าถึงคุณสมบัติหรือไม่เมื่อมันผ่านวัตถุ (ใช้สำหรับ ... ในลูปหรือวิธีการวัตถุคีย์) ค่าเริ่มต้นเป็นเท็จ
นอกเหนือจากแอตทริบิวต์ทั่วไปสองตัวด้านบนตัวอธิบายข้อมูลมีสองแอตทริบิวต์ต่อไปนี้:
- ค่าใช้เพื่อระบุค่าของคุณสมบัตินี้ค่าเริ่มต้นจะไม่ได้กำหนดไว้
- ใช้งานได้เพื่อระบุว่าค่าของคุณสมบัติอนุญาตให้เปลี่ยนค่าของทรัพย์สินได้หรือไม่ ค่าเริ่มต้นเป็นเท็จ
มีสองคุณสมบัติสำหรับการเข้าถึงตัวบ่งชี้:
- Get ใช้เพื่อระบุ accessor (getter เป็นหลักเป็นฟังก์ชั่น) เมื่อเข้าถึงคุณสมบัติและค่าส่งคืนของ accessor คือค่าของคุณสมบัติ ค่าเริ่มต้นไม่ได้กำหนดไว้
- SET ใช้เพื่อระบุตัวประเมิน (setter เป็นหลักเป็นฟังก์ชัน) เมื่อเข้าถึงคุณสมบัตินี้ ผู้ประเมินยอมรับพารามิเตอร์ ค่าเริ่มต้นไม่ได้กำหนดไว้
เราสามารถใช้ Object.defineProperty เพื่อตั้งค่าตัวบ่งชี้คุณสมบัติของวัตถุ ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
// ใช้ __proto__
Object.defineProperty (obj, 'key', {
__proto__: null, // ไม่มีคุณสมบัติที่สืบทอดมา
ค่า: 'คงที่' // ไม่สามารถระบุได้
// ไม่สามารถกำหนดค่าได้
// ไม่สามารถเขียนได้
// เป็นค่าเริ่มต้น
-
จากตัวอย่างข้างต้นเราจะเห็นว่าตัวอธิบายมีลักษณะของการสืบทอด เราตั้งค่า __proto__ ของวัตถุ descriptor เป็น null อย่างชัดเจนซึ่งหลีกเลี่ยงการสืบทอดแอตทริบิวต์ที่เกี่ยวข้องจาก Object.prototype แน่นอนว่าเราสามารถตั้งค่าคุณสมบัติทั้งหมดของ descriptor ได้อย่างชัดเจน:
การคัดลอกรหัสมีดังนี้:
// มีความชัดเจน
Object.defineProperty (obj, 'key', {
enumerable: FALSE,
สามารถกำหนดค่าได้: เท็จ
เขียนได้: เท็จ
ค่า: 'คงที่'
-
เอฟเฟกต์นี้เหมือนกับรหัสชิ้นแรก
นี่เป็นอีกตัวอย่างหนึ่งของตัวบ่งชี้การเข้าถึง:
การคัดลอกรหัสมีดังนี้:
// ตัวอย่างของคุณสมบัติวัตถุที่เพิ่มด้วย defelEproperty ด้วยตัวอธิบายคุณสมบัติ accessor
var bvalue = 38;
Object.defineProperty (obj, 'key', {
รับ: function () {return bvalue; -
ชุด: ฟังก์ชั่น (newValue) {bvalue = newValue; -
enumerable: จริง
สามารถกำหนดค่าได้: จริง
-
ควรสังเกตว่าตัวอธิบายการเข้าถึงและตัวอธิบายข้อมูลไม่สามารถสับสนได้ มันผิดที่จะเขียนสิ่งต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
// คุณไม่สามารถลองผสมทั้งสองอย่าง:
Object.defineProperty (obj, 'ความขัดแย้ง', {
ค่า: 0x9f91102
รับ: function () {return 0xDeadBeef; -
-
// โยน typeError: ตัวอธิบายคุณสมบัติจะต้องไม่ระบุค่า
// หรือเขียนได้เมื่อมีการระบุ getter หรือ setter
ประเภทของ
หากคุณต้องการทราบประเภทของตัวแปรที่รันไทม์คุณสามารถใช้ตัวดำเนินการประเภท ค่าส่งคืนของ typeof มีดังนี้:
สิ่งหนึ่งที่ต้องสังเกตคือ typeof null == "วัตถุ" ตามมาตรฐาน ECMASCRIPT 5.1 ประเภท NULL ควรเป็นประเภทพื้นฐาน ทำไมวัตถุกลับมาที่นี่? เหตุผลคือ:
ใน JavaScript 1.0 ค่าใน JavaScript จะถูกแสดงโดยโครงสร้างเช่นแท็กประเภทและค่าจริง ประเภทการตั้งค่าสถานะของวัตถุคือ 0 และ null แสดงถึงตัวชี้โมฆะ (0x00) ในภาษา C ดังนั้นค่าสถานะของค่า NULL คือ 0
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ โปรดดูหากคุณต้องการ