"โหมดเข้มงวด" เป็นไวยากรณ์ใหม่ที่กำหนดไว้ใน ECMA-262 Edition 5 ซึ่งบ่งชี้ว่าจำเป็นต้องดำเนินการโดยใช้ไวยากรณ์ JavaScript ที่เข้มงวด บางวิธีการเขียนที่ใช้ในอดีตจะโยนข้อยกเว้น SyntaxError เช่น:
1. ไม่มีการประกาศ var ก่อนตัวแปร
2. ใช้ไวยากรณ์แปดเท่า: var n = 023 และ var s = "/047"
3. ใช้กับข้อความ
4. ใช้ลบเพื่อลบชื่อตัวแปร (ไม่ใช่ชื่อแอตทริบิวต์): ลบ myVariable
5. ใช้การประเมินหรืออาร์กิวเมนต์เป็นชื่อตัวแปรหรือชื่อฟังก์ชัน
6. ใช้คำที่สงวนไว้ในอนาคต (อาจใช้ใน eCmascript 6): อุปกรณ์, อินเทอร์เฟซ, ปล่อย, แพ็คเกจ, ส่วนตัว, ป้องกัน, สาธารณะ, คงที่และให้ผลผลิตเป็นชื่อตัวแปรหรือชื่อฟังก์ชั่น
7. ใช้การประกาศฟังก์ชั่นในบล็อกคำสั่ง: if (a <b) {function f () {}}
8. ข้อผิดพลาดอื่น ๆ
8.1. ใช้ชื่อแอตทริบิวต์ที่เหมือนกันสองชื่อในขนาดวัตถุย่อยของวัตถุ: {a: 1, b: 3, a: 7}
8.2. ใช้ชื่อพารามิเตอร์ที่เหมือนกันสองชื่อในพารามิเตอร์ฟังก์ชัน: ฟังก์ชัน F (a, b, b) {}
รายละเอียดเหล่านี้อธิบายไว้ในรายละเอียดด้านล่าง
1. ทำไมต้องใช้ "โหมดเข้มงวด"
วัตถุประสงค์ของการสร้าง "โมเดลที่เข้มงวด" เป็นหลักดังนี้:
1. กำจัดแง่มุมที่ไม่สมเหตุสมผลและไม่สมบูรณ์ของไวยากรณ์จาวาสคริปต์และลดพฤติกรรมแปลก ๆ
2. กำจัดความไม่มั่นคงในการทำงานของรหัสและให้ความมั่นใจกับความปลอดภัยของรหัสที่ทำงาน
3. ปรับปรุงประสิทธิภาพของคอมไพเลอร์และเพิ่มความเร็วในการทำงาน
4. วางรากฐานสำหรับ JavaScript เวอร์ชันใหม่ในอนาคต
"โหมดที่เข้มงวด" สะท้อนให้เห็นถึงทิศทางการพัฒนาที่สมเหตุสมผลปลอดภัยและเข้มงวดยิ่งขึ้นของ JavaScript เบราว์เซอร์กระแสหลักรวมถึง IE 10 ได้ให้การสนับสนุนแล้วและโครงการสำคัญหลายโครงการได้เริ่มยอมรับมันอย่างเต็มที่
ในทางกลับกันรหัสเดียวกันอาจมีผลลัพธ์การรันที่แตกต่างกันใน "โหมดเข้มงวด"; ข้อความบางอย่างที่สามารถเรียกใช้ใน "โหมดปกติ" จะไม่ทำงานใน "โหมดเข้มงวด" การเรียนรู้เนื้อหาเหล่านี้จะช่วยให้คุณเข้าใจ JavaScript อย่างระมัดระวังและลึกซึ้งยิ่งขึ้นทำให้คุณเป็นโปรแกรมเมอร์ที่ดีขึ้น
บทความนี้จะให้คำแนะนำโดยละเอียดเกี่ยวกับ "โมเดลที่เข้มงวด"
2. ประกาศ "โหมดเข้มงวด"
การประกาศ "โหมดเข้มงวด" นั้นง่ายและมีเพียงคำสั่งเดียว:
การคัดลอกรหัสมีดังนี้: "ใช้อย่างเข้มงวด";
หมายเหตุ: เบราว์เซอร์รุ่นเก่าจะถือว่าเป็นสตริงปกติและไม่สนใจ
3. ประกาศตำแหน่งและความสัมพันธ์ตามบริบทของ "โหมดเข้มงวด"
"โหมดเข้มงวด" ส่วนใหญ่มีผลต่อขอบเขตที่อยู่ หากใช้ในฟังก์ชั่นมันจะไม่เปลี่ยนขอบเขตทั่วโลกและฟังก์ชั่นที่ไม่ได้ใช้อื่น ๆ เป็น "โหมดเข้มงวด" นั่นคือขอบเขตของการประกาศรูปแบบที่เข้มงวดขึ้นอยู่กับบริบทของมัน หากมีการประกาศโหมดที่เข้มงวดในบริบททั่วโลก (นอกขอบเขตของฟังก์ชั่น) รหัสทั้งหมดในโปรแกรมอยู่ในโหมดที่เข้มงวด หากมีการประกาศรูปแบบที่เข้มงวดในฟังก์ชั่นรหัสทั้งหมดในฟังก์ชั่นอยู่ในรูปแบบที่เข้มงวด ตัวอย่างเช่นในตัวอย่างต่อไปนี้รหัสทั้งหมดอยู่ในโหมดที่เข้มงวดและการประกาศตัวแปรนอกฟังก์ชั่นจะทำให้เกิดข้อผิดพลาดทางไวยากรณ์: "ตัวแปรไม่ได้กำหนดไว้ในโหมดที่เข้มงวด" มีสองวิธีในการเรียก "โหมดเข้มงวด" และเหมาะสำหรับโอกาสที่แตกต่างกัน
1. สำหรับไฟล์สคริปต์ทั้งหมด
ใส่ "ใช้อย่างเข้มงวด" ในบรรทัดแรกของไฟล์สคริปต์และสคริปต์ทั้งหมดจะทำงานใน "โหมดเข้มงวด" หากคำสั่งบรรทัดนี้ไม่ได้อยู่ในบรรทัดแรกมันไม่ถูกต้องและสคริปต์ทั้งหมดทำงานใน "โหมดปกติ" สิ่งนี้ต้องการความสนใจเป็นพิเศษหากไฟล์รหัสของโหมดต่าง ๆ ถูกรวมเข้ากับไฟล์เดียว
(พูดอย่างเคร่งครัดตราบใดที่คำสั่งที่สร้างผลการทำงานจริงไม่ได้นำหน้า "ใช้อย่างเข้มงวด" อาจไม่อยู่ในบรรทัดแรกเช่นโดยตรงตามเครื่องหมายอัฒภาคที่ว่างเปล่า)
การคัดลอกรหัสมีดังนี้:
<script>
"ใช้เข้มงวด";
console.log ("นี่คือโหมดที่เข้มงวด");
</script>
<script>
console.log ("นี่คือโหมดปกติ");
</script>
รหัสด้านบนระบุว่ามีรหัส JavaScript สองชิ้นในหน้าเว็บในทางกลับกัน แท็กสคริปต์ก่อนหน้านี้เป็นโหมดที่เข้มงวด แต่อันหลังไม่ได้
2. สำหรับฟังก์ชั่นเดียว
ใส่ "ใช้อย่างเข้มงวด" ในบรรทัดแรกของร่างกายฟังก์ชั่นและฟังก์ชั่นทั้งหมดทำงานใน "โหมดเข้มงวด"
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นเข้มงวด () {
"ใช้เข้มงวด";
กลับ "นี่เป็นรูปแบบที่เข้มงวด";
-
ฟังก์ชัน notstrict () {
กลับ "นี่คือโหมดปกติ";
-
3. วิธีแก้ปัญหาสำหรับไฟล์สคริปต์
เนื่องจากวิธีการโทรครั้งแรกไม่เอื้อต่อการรวมไฟล์จึงเป็นการดีกว่าที่จะยืมวิธีที่สองและวางไฟล์สคริปต์ทั้งหมดในฟังก์ชันที่ไม่ระบุชื่อที่ดำเนินการทันที
การคัดลอกรหัสมีดังนี้:
(การทำงาน (){
"ใช้เข้มงวด";
// รหัสบางส่วนที่นี่
-
4. ไวยากรณ์และพฤติกรรมเปลี่ยนแปลงภายใต้ "โหมดเข้มงวด"
"โหมดเข้มงวด" ได้ทำการเปลี่ยนแปลงบางอย่างกับไวยากรณ์และพฤติกรรมของจาวาสคริปต์
1. การประกาศอย่างชัดเจนของตัวแปรทั่วโลก
ในโหมดปกติเมื่อใช้ตัวแปรเราไม่จำเป็นต้องใช้ VAR เพื่อประกาศ (ประกาศอย่างชัดเจน) แต่ในโหมดที่เข้มงวดเราต้องใช้ VAR เพื่อประกาศก่อนใช้ตัวแปรมิฉะนั้นจะเกิดข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
V = 1; // มีการรายงานข้อผิดพลาด V ไม่ได้ประกาศ
สำหรับ (i = 0; i <2; i ++) {// มีรายงานข้อผิดพลาดฉันไม่ได้ประกาศ
-
ดังนั้นในโหมดที่เข้มงวดจะต้องประกาศตัวแปรด้วยคำสั่ง VAR ก่อนการใช้งาน
2. การผูกคงที่
คุณลักษณะของภาษา JavaScript คือมันอนุญาตให้ "การเชื่อมโยงแบบไดนามิก" นั่นคือซึ่งเป็นวัตถุคุณสมบัติและวิธีการบางอย่างที่ไม่ได้รับการพิจารณาในเวลาที่รวบรวม แต่เมื่อรันไทม์
โหมดที่เข้มงวดวางข้อ จำกัด บางประการเกี่ยวกับการเชื่อมโยงแบบไดนามิก ในบางกรณีอนุญาตให้มีการผูกมัดแบบคงที่เท่านั้น กล่าวอีกนัยหนึ่งซึ่งจะมีการกำหนดคุณลักษณะและวิธีการของคุณลักษณะในระหว่างขั้นตอนการรวบรวม สิ่งนี้จะช่วยปรับปรุงประสิทธิภาพการรวบรวมทำให้รหัสอ่านง่ายขึ้นและเกิดอุบัติเหตุน้อยลง
โดยเฉพาะด้านต่อไปนี้มีส่วนร่วม
(1) ใช้คำสั่งใช้กับคำสั่ง
เนื่องจากไม่สามารถกำหนดคำสั่งด้วยเวลาคอมไพล์ได้ซึ่งวัตถุใดที่คุณลักษณะเป็นของ
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var v = 1;
ด้วย (o) {// ข้อผิดพลาดไวยากรณ์
V = 2;
-
(2) สร้างขอบเขตการประเมิน
ในโหมดปกติภาษา JavaScript มีสองขอบเขตตัวแปร: ขอบเขตขอบเขตและขอบเขตฟังก์ชัน โหมดที่เข้มงวดสร้างขอบเขตที่สาม: ขอบเขตการประเมิน
ในโหมดปกติขอบเขตของคำสั่ง eval ขึ้นอยู่กับว่าอยู่ในขอบเขตทั่วโลกหรือในขอบเขตการทำงาน ในโหมดที่เข้มงวดคำสั่ง Eval เป็นขอบเขตและไม่สามารถสร้างตัวแปรทั่วโลกได้อีกต่อไป ตัวแปรที่สร้างขึ้นสามารถใช้ภายใน eval เท่านั้น
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var x = 2;
console.info (eval ("var x = 5; x")); // 5
console.info (x); // 2
3. มาตรการความปลอดภัยที่เพิ่มขึ้น
(1) ห้ามคีย์เวิร์ดนี้ชี้ไปที่วัตถุทั่วโลก
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f () {
กลับมา!
-
// return false เพราะ "this" ชี้ไปที่วัตถุทั่วโลก "! this" เป็นเท็จ
ฟังก์ชั่น f () {
"ใช้เข้มงวด";
กลับมา!
-
// ส่งคืนจริงเพราะในโหมดที่เข้มงวดค่าของสิ่งนี้จะไม่ได้กำหนดดังนั้น "สิ่งนี้" เป็นจริง
ดังนั้นเมื่อใช้ตัวสร้างถ้าคุณลืมเพิ่มใหม่สิ่งนี้จะไม่ชี้ไปที่วัตถุทั่วโลกอีกต่อไป แต่รายงานข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f () {
"ใช้เข้มงวด";
this.a = 1;
-
f (); // ข้อผิดพลาดสิ่งนี้ไม่ได้กำหนดไว้
ในการเรียกใช้ฟังก์ชันธรรมดา F () ค่าของสิ่งนี้จะชี้ไปที่วัตถุทั่วโลก ในโหมดที่เข้มงวดค่าของสิ่งนี้จะชี้ไปที่ไม่ได้กำหนด เมื่อฟังก์ชั่นถูกเรียกผ่านการโทรและใช้หากพารามิเตอร์ค่านี้ผ่านเป็นค่าดั้งเดิม (สตริง, ตัวเลข, ค่าบูลีน) ยกเว้นค่า NULL และไม่ได้กำหนดค่าของสิ่งนี้จะกลายเป็นวัตถุ wrapper ที่สอดคล้องกับค่าดั้งเดิม หากค่าของพารามิเตอร์ค่านี้ไม่ได้กำหนดหรือเป็นโมฆะค่าของสิ่งนี้จะชี้ไปที่วัตถุทั่วโลก ในโหมดที่เข้มงวดค่าของค่านี้คือค่าของพารามิเตอร์ค่านี้โดยไม่มีการแปลงประเภทใด ๆ
(2) ห้ามไม่ให้สำรวจสแต็คการโทรภายในฟังก์ชั่น
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f1 () {
"ใช้เข้มงวด";
f1.Caller; // รายงานข้อผิดพลาด
f1.Arguments; // รายงานข้อผิดพลาด
-
F1 ();
4. ปิดการใช้งานการลบตัวแปร
ตัวแปรไม่สามารถลบได้ในโหมดที่เข้มงวด เฉพาะคุณสมบัติของวัตถุที่กำหนดค่าได้ถูกตั้งค่าเป็นจริงเท่านั้นที่สามารถลบได้
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var x;
ลบ x; // ข้อผิดพลาดไวยากรณ์
var o = object.create (null, 'x', {
ค่า: 1,
สามารถกำหนดค่าได้: จริง
-
ลบวัว; // ลบสำเร็จ
5. ข้อผิดพลาดที่ชัดเจน
ในโหมดปกติหากคุณกำหนดคุณสมบัติแบบอ่านอย่างเดียวของวัตถุจะไม่มีข้อผิดพลาดและมันจะล้มเหลวอย่างเงียบ ๆ ในโหมดที่เข้มงวดจะมีการรายงานข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var o = {};
Object.defineProperty (o, "v", {ค่า: 1, เขียนได้: false});
ov = 2; // รายงานข้อผิดพลาด
ในโหมดที่เข้มงวดหากคุณกำหนดคุณสมบัติการอ่านโดยใช้เมธอด Getter จะมีการรายงานข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var o = {
รับ v () {return 1; -
-
ov = 2; // รายงานข้อผิดพลาด
ในโหมดที่เข้มงวดการเพิ่มแอตทริบิวต์ใหม่ให้กับวัตถุที่ถูกห้ามไม่ให้ขยายจะส่งผลให้เกิดข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var o = {};
Object.preventExtensions (O);
ov = 1; // รายงานข้อผิดพลาด
ในโหมดที่เข้มงวดการลบคุณสมบัติ undelete จะทำให้เกิดข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
ลบ Object.prototype; // รายงานข้อผิดพลาด
6. การเปลี่ยนชื่อข้อผิดพลาด
โหมดที่เข้มงวดได้เพิ่มข้อผิดพลาดทางไวยากรณ์บางอย่าง
(1) วัตถุไม่สามารถมีแอตทริบิวต์ที่มีชื่อซ้ำ
ในโหมดปกติหากวัตถุมีแอตทริบิวต์ที่ซ้ำกันหลายรายการแอตทริบิวต์ล่าสุดที่กำหนดจะแทนที่ค่าก่อนหน้า ในโหมดที่เข้มงวดนี่เป็นข้อผิดพลาดทางไวยากรณ์
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var o = {
P: 1,
P: 2
- // ข้อผิดพลาดไวยากรณ์
(2) ฟังก์ชั่นไม่สามารถมีพารามิเตอร์ที่มีชื่อซ้ำ
ในโหมดปกติหากฟังก์ชั่นมีพารามิเตอร์หลายตัวที่มีชื่อที่ซ้ำกันสามารถอ่านได้ด้วยอาร์กิวเมนต์ [i] ในโหมดที่เข้มงวดนี่เป็นข้อผิดพลาดทางไวยากรณ์
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
ฟังก์ชั่น f (a, a, b) {// ข้อผิดพลาดไวยากรณ์
กลับ ;
-
7. ไม่มีการห้ามสัญกรณ์ Octal
ในโหมดปกติหากบิตแรกของจำนวนเต็มคือ 0 นั่นหมายความว่านี่เป็นหมายเลขแปดเท่าเช่น 0100 เท่ากับ 64 ในทศนิยม โหมดที่เข้มงวดห้ามการเป็นตัวแทนนี้ หากบิตแรกของจำนวนเต็มเป็น 0 จะมีการรายงานข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var n = 0100; // ข้อผิดพลาดไวยากรณ์
8. ข้อ จำกัด ของวัตถุอาร์กิวเมนต์
อาร์กิวเมนต์เป็นวัตถุพารามิเตอร์ของฟังก์ชั่นและโหมดที่เข้มงวด จำกัด การใช้งาน
(1) ไม่อนุญาตให้มีการกำหนดอาร์กิวเมนต์
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
อาร์กิวเมนต์ ++; // ข้อผิดพลาดไวยากรณ์
var obj = {set p (อาร์กิวเมนต์) {}}; // ข้อผิดพลาดไวยากรณ์
ลอง {} catch (อาร์กิวเมนต์) {} // ข้อผิดพลาดไวยากรณ์
ฟังก์ชั่นอาร์กิวเมนต์ () {} // ข้อผิดพลาดไวยากรณ์
var f = ฟังก์ชั่นใหม่ ("อาร์กิวเมนต์", "'ใช้อย่างเข้มงวด'; return 17;"); // ข้อผิดพลาดไวยากรณ์
(2) อาร์กิวเมนต์ไม่ติดตามการเปลี่ยนแปลงของพารามิเตอร์อีกต่อไป
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f (a) {
a = 2;
กลับ [A, อาร์กิวเมนต์ [0]];
-
f (1); // โหมดปกติคือ [2,2]
ฟังก์ชั่น f (a) {
"ใช้เข้มงวด";
a = 2;
กลับ [A, อาร์กิวเมนต์ [0]];
-
f (1); // โหมดที่เข้มงวดคือ [2,1]
(3) การใช้อาร์กิวเมนต์ห้ามใช้ callee
ซึ่งหมายความว่าคุณไม่สามารถเรียกตัวเองในฟังก์ชั่นที่ไม่ระบุชื่อได้
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
var f = function () {return arguments.callee; -
f (); // รายงานข้อผิดพลาด
9. ฟังก์ชั่นจะต้องประกาศในระดับบนสุด
ในอนาคต JavaScript เวอร์ชันใหม่จะแนะนำ "ขอบเขตระดับบล็อก" ในการจัดตำแหน่งกับเวอร์ชันใหม่โหมดที่เข้มงวดจะอนุญาตให้มีการประกาศฟังก์ชั่นที่ระดับสูงสุดของขอบเขตหรือขอบเขตฟังก์ชัน นั่นคือไม่ได้รับอนุญาตให้ประกาศฟังก์ชั่นภายในบล็อกรหัสที่ไม่ฟังก์ชั่น
การคัดลอกรหัสมีดังนี้:
"ใช้เข้มงวด";
ถ้า (จริง) {
ฟังก์ชัน f () {} // ข้อผิดพลาดไวยากรณ์
-
สำหรับ (var i = 0; i <5; i ++) {
ฟังก์ชัน f2 () {} // ข้อผิดพลาดไวยากรณ์
-
10. เก็บคำพูด
เพื่อเปลี่ยนไปใช้ JavaScript เวอร์ชันใหม่ในอนาคตคำที่สงวนไว้บางคำได้ถูกเพิ่มเข้ามาในโหมดที่เข้มงวด: การใช้งาน, อินเทอร์เฟซ, ปล่อย, แพ็คเกจ, ส่วนตัว, การป้องกัน, สาธารณะ, คงที่
การใช้คำเหล่านี้เป็นชื่อตัวแปรจะส่งผลให้เกิดข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
แพ็คเกจฟังก์ชัน (ป้องกัน) {// ข้อผิดพลาดไวยากรณ์
"ใช้เข้มงวด";
การใช้งาน VAR; // ข้อผิดพลาดไวยากรณ์
-
นอกจากนี้ ECMASCRIPT เวอร์ชันที่ห้ายังกำหนดคำอื่น ๆ ที่สงวนไว้ (คลาส, enum, ส่งออก, ขยาย, นำเข้า, super), เช่นเดียวกับคำที่สงวนไว้ในเบราว์เซอร์ที่สำคัญซึ่งไม่สามารถใช้เป็นชื่อตัวแปรได้