โหมดที่เข้มงวดเป็นคุณสมบัติใหม่ของ ECMASCRIPT 5. ช่วยให้คุณสามารถวางโปรแกรมทั้งหมดหรือฟังก์ชั่นในบริบทการดำเนินการ "เข้มงวด" บริบทที่เข้มงวดนี้ป้องกันการดำเนินการบางอย่างและทำให้เกิดข้อยกเว้นมากขึ้น
ในขณะที่ ECMASCRIPT 5 นั้นเข้ากันได้กับ ECMASCRIPT 3 ในโหมดที่เข้มงวด แต่คุณสมบัติทั้งหมดที่ไม่ได้รับการสนับสนุนใน ECMASCRIPT 3 จะถูกปิดใช้งาน (หรือโยนข้อผิดพลาด) แทนที่จะเข้ากันได้
เปิดใช้งานโหมดที่เข้มงวดมีประโยชน์ดังต่อไปนี้:
1. จับข้อผิดพลาดในการเขียนโปรแกรมและโยนข้อยกเว้น
2. ป้องกันการดำเนินงานที่ค่อนข้าง "ไม่ปลอดภัย" (เช่นการเข้าถึงตัวแปรทั่วโลก) จากการดำเนินการและข้อยกเว้นจะถูกโยนลงไป
3. ปิดการใช้งานคุณสมบัติที่สับสน
ข้อมูลส่วนใหญ่เกี่ยวกับโหมดที่เข้มงวดสามารถพบได้ในหน้า 223 ของรหัส ES5 [PDF]
(หมายเหตุ: โหมดที่เข้มงวดของ Ecmascript 5 นั้นแตกต่างจากโหมดที่เข้มงวดของ Firefox)
วิธีเปิดใช้งานโหมดที่เข้มงวด
เพิ่มคำสั่งนี้ที่จุดเริ่มต้นของโปรแกรมเพื่อเปิดใช้งานโหมดที่เข้มงวดสำหรับสคริปต์ทั้งหมด:
การคัดลอกรหัสมีดังนี้:
'ใช้อย่างเข้มงวด';
นอกจากนี้คุณยังสามารถเปิดใช้งานโหมดที่เข้มงวดภายในฟังก์ชั่นเท่านั้นเพื่อที่จะไม่ส่งผลกระทบต่อภายนอก:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น iMstrict () {
'ใช้อย่างเข้มงวด';
// ... รหัสของคุณ ...
-
คำสั่งที่เปิดใช้งานโหมดที่เข้มงวดเป็นเพียงสตริงปกติ "ใช้อย่างเข้มงวด" โดยไม่มีไวยากรณ์ใหม่ ซึ่งหมายความว่าจะไม่มีผลกระทบเชิงลบต่อเบราว์เซอร์เก่า
หนึ่งแอปพลิเคชั่นที่ใช้งานได้จริงของการเปิดใช้งานโหมดที่เข้มงวดภายในฟังก์ชั่นคือการกำหนดไลบรารีคลาส JavaScript ทั้งหมดภายในฟังก์ชั่นโหมดที่เข้มงวดเพื่อไม่ให้มีผลต่อรหัสภายนอก:
การคัดลอกรหัสมีดังนี้:
// รหัสที่ไม่ใช่ Strict ...
(การทำงาน(){
"ใช้เข้มงวด";
// กำหนดห้องสมุดของคุณอย่างเคร่งครัด ...
-
// รหัสที่ไม่ใช่ Strict ...
ดังนั้นมีการเปลี่ยนแปลงอะไรบ้างในสคริปต์ในโหมดที่เข้มงวด?
ตัวแปรและคุณสมบัติ
การกำหนดตัวแปรที่ไม่ได้กำหนดจะล้มเหลวแทนที่จะใช้ตัวแปรนี้เป็นตัวแปรส่วนกลาง
การเขียนคุณสมบัติที่มีคุณสมบัติเป็นเท็จการลบการลบคุณสมบัติด้วยคุณสมบัติที่กำหนดค่าได้ด้วยเท็จหรือเพิ่มคุณสมบัติที่มีคุณสมบัติที่ขยายได้ด้วยเท็จจะส่งผลให้เกิดข้อผิดพลาด ในอดีตการดำเนินการเหล่านี้ไม่ได้มีข้อยกเว้น แต่ก็ล้มเหลวอย่างเงียบ ๆ
การดำเนินการลบการดำเนินการบนตัวแปรฟังก์ชั่นหรือพารามิเตอร์ฟังก์ชันจะทำให้เกิดข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
var foo = 'ทดสอบ';
การทดสอบฟังก์ชั่น () {}
ลบ foo; // ข้อผิดพลาด
ลบการทดสอบ; // ข้อผิดพลาด
ฟังก์ชั่น test2 (arg) {
ลบ arg; // ข้อผิดพลาด
-
การกำหนดคุณสมบัติเดียวกันภายในคอนเทนเนอร์วัตถุจะทำให้เกิดข้อยกเว้นที่จะโยน:
การคัดลอกรหัสมีดังนี้:
// ข้อผิดพลาด
{foo: true, foo: false}
การประเมิน
การใช้ชื่อ "eval" (วัตถุประสงค์หลักคือการชี้ฟังก์ชั่นการประเมินไปยังคุณสมบัติของตัวแปรหรือวัตถุ)
การคัดลอกรหัสมีดังนี้:
// ทั้งหมดสร้างข้อผิดพลาด ...
obj.eval = ...
obj.foo = eval;
var eval = ... ;
สำหรับ (var eval ใน ... ) {}
ฟังก์ชั่น evals () {}
การทดสอบฟังก์ชั่น (eval) {}
ฟังก์ชั่น (eval) {}
ฟังก์ชั่นใหม่ ("eval")
นอกจากนี้การประกาศตัวแปรใหม่ผ่านการประเมินจะไม่ถูกต้อง:
การคัดลอกรหัสมีดังนี้:
eval ("var a = false;");
พิมพ์ (typeof a); // ไม่ได้กำหนด
การทำงาน
วัตถุอาร์กิวเมนต์ใหม่จะทำให้เกิดข้อผิดพลาด:
การคัดลอกรหัสมีดังนี้:
อาร์กิวเมนต์ = [... ]; // ไม่อนุญาต
พารามิเตอร์ที่มีชื่อเดียวกันจะทำให้เกิดข้อผิดพลาด:
การคัดลอกรหัสมีดังนี้:
(ฟังก์ชั่น (foo, foo) {}) // ข้อผิดพลาด
การเข้าถึงอาร์กิวเมนต์ผู้เรียกเก็บเงินและอาร์กิวเมนต์ Callee โยนข้อยกเว้น ดังนั้นฟังก์ชันที่ไม่ระบุชื่อใด ๆ ที่ต้องใช้จะต้องตั้งชื่อก่อนเช่น:
การคัดลอกรหัสมีดังนี้:
settimeout (ฟังก์ชั่นในภายหลัง () {
// ทำสิ่งของ ...
settimeout (ภายหลัง, 1,000);
}, 1,000);
ไม่มีการโต้แย้งคุณสมบัติผู้โทรและ Callee ของฟังก์ชั่นอีกต่อไปและการดำเนินการเพื่อกำหนดพวกเขาก็เป็นสิ่งต้องห้ามเช่นกัน
การคัดลอกรหัสมีดังนี้:
การทดสอบฟังก์ชั่น () {}
test.caller = 'ผู้โทร'; // ข้อผิดพลาด
ในที่สุดข้อผิดพลาดที่ยาวนาน (และน่ารำคาญมาก) ได้รับการแก้ไขแล้ว: เมื่อใช้ null หรือ undefined เป็นพารามิเตอร์แรกของฟังก์ชัน prototype.call หรือ function.prototype.apply วิธีการนี้ภายในฟังก์ชั่นจะชี้ไปที่วัตถุทั่วโลก และโหมดที่เข้มงวดจะป้องกันการดำเนินการและโยนข้อยกเว้น:
การคัดลอกรหัสมีดังนี้:
(function () {... }) การโทร (null); // ข้อยกเว้น
กับ() { }
คำสั่งด้วย () {} แขวนอยู่ในโหมดที่เข้มงวดอย่างสมบูรณ์