รูปแบบที่เข้มงวดที่แนะนำใน ECMAScript5 ช่วยให้นักพัฒนามีภาษาจาวาสคริปต์ที่ "ดีกว่า" โดยอนุญาตให้สภาพแวดล้อมการทำงานของจาวาสคริปต์เพื่อจัดการกับบางส่วนที่พบบ่อยที่สุดและยากที่จะตรวจจับข้อผิดพลาดในกระบวนการพัฒนา เป็นเวลานานฉันมีข้อสงสัยเกี่ยวกับโหมดที่เข้มงวดเพราะมีเพียง Firefox เท่านั้นที่รองรับโหมดที่เข้มงวด แต่วันนี้เบราว์เซอร์กระแสหลักทั้งหมดรองรับโหมดที่เข้มงวดในเวอร์ชันล่าสุดของพวกเขา (รวมถึง IE10, OperA12 และ Android 4, iOS5) ถึงเวลาเริ่มใช้โหมดที่เข้มงวด
การเล่นแบบโมเดลที่เข้มงวดสามารถมีบทบาทอย่างไร?
รูปแบบที่เข้มงวดแนะนำการเปลี่ยนแปลงมากมายกับ JavaScript และฉันแบ่งออกเป็นสองประเภท (ชัดเจนและละเอียดอ่อน) เป้าหมายของการปรับปรุงเล็กน้อยคือการแก้ไขปัญหารายละเอียดบางอย่างในจาวาสคริปต์ปัจจุบันซึ่งฉันจะไม่เข้าไปในเชิงลึกที่นี่ หากคุณสนใจโปรดอ่านเอกสารที่ยอดเยี่ยมที่เขียนโดย Dmitry Soshnikov ECMA-262-5 ในรายละเอียดบทที่ 2 โหมดเข้มงวด ฉันแนะนำการเปลี่ยนแปลงที่ชัดเจนซึ่งแนะนำโดยโหมดที่เข้มงวดแนวคิดที่คุณควรรู้ก่อนที่คุณจะใช้โหมดที่เข้มงวดและการเปลี่ยนแปลงเหล่านั้นที่ช่วยคุณได้มากที่สุด
ก่อนที่คุณจะเริ่มเรียนรู้คุณสมบัติเฉพาะโปรดจำไว้ว่าหนึ่งในเป้าหมายสำคัญของโหมดที่เข้มงวดคือช่วยให้คุณสามารถดีบักได้เร็วขึ้นและสะดวกยิ่งขึ้น เป็นการดีกว่าที่จะโยนข้อผิดพลาดที่ชัดเจนเมื่อสภาพแวดล้อมรันไทม์ค้นพบปัญหามากกว่าที่จะล้มเหลวอย่างเงียบ ๆ หรือทำอย่างแปลกประหลาด (ซึ่งมักจะเป็นกรณีของสภาพแวดล้อมที่ใช้ JavaScript ที่ไม่เปิดโหมดที่เข้มงวด) โหมดที่เข้มงวดทำให้เกิดข้อผิดพลาดมากขึ้น แต่นั่นเป็นสิ่งที่ดีเพราะข้อผิดพลาดเหล่านี้จะดึงดูดความสนใจของคุณและแก้ไขปัญหาที่อาจเกิดขึ้นมากมายซึ่งก่อนหน้านี้ยากที่จะมองเห็น
ลบด้วยคำหลัก
ขั้นแรกคำสั่ง WITH จะถูกลบออกในโหมดที่เข้มงวดและรหัสที่มีคำสั่งด้วยคำสั่งจะโยนข้อยกเว้นในโหมดที่เข้มงวด ดังนั้นขั้นตอนแรกในการใช้โหมดที่เข้มงวด: ตรวจสอบให้แน่ใจว่าคุณไม่ได้ใช้ในรหัสของคุณ
การคัดลอกรหัสมีดังนี้:
// รหัส JavaScript ต่อไปนี้จะทำให้เกิดข้อผิดพลาดในโหมดที่เข้มงวด
ด้วย (ตำแหน่ง) {
การแจ้งเตือน (href);
-
ป้องกันการกำหนดค่าโดยไม่คาดคิดให้กับตัวแปรทั่วโลกโดยไม่คาดคิด
ประการที่สองตัวแปรท้องถิ่นจะต้องประกาศก่อนการมอบหมาย ก่อนที่จะเปิดใช้งานโหมดที่เข้มงวดตัวแปรส่วนกลางที่มีชื่อเดียวกันจะถูกสร้างขึ้นโดยอัตโนมัติเมื่อคัดลอกสำหรับตัวแปรท้องถิ่นที่ไม่ได้ประกาศ นี่เป็นหนึ่งในข้อผิดพลาดที่พบบ่อยที่สุดในโปรแกรม JavaScript และเมื่อพยายามทำสิ่งนี้ในโหมดที่เข้มงวดข้อยกเว้นที่ชัดเจนจะถูกโยนทิ้ง
การคัดลอกรหัสมีดังนี้:
// ข้อยกเว้นจะถูกโยนในโหมดเข้มงวด
(การทำงาน() {
SomeundeclaredVar = "foo";
-
ในฟังก์ชั่นนี้ไม่ชี้ไปที่ Global โดยค่าเริ่มต้นอีกต่อไป
การเปลี่ยนแปลงที่สำคัญอีกประการหนึ่งในโหมดที่เข้มงวดคือฟังก์ชั่นนี้ที่ไม่ได้กำหนดหรือไม่ได้กำหนด (NULL หรือไม่ได้กำหนด) ไม่ได้ชี้ไปที่สภาพแวดล้อมทั่วโลกโดยค่าเริ่มต้น สิ่งนี้จะทำให้เกิดข้อผิดพลาดในการดำเนินการโค้ดที่ขึ้นอยู่กับพฤติกรรมเริ่มต้นของสิ่งนี้ในฟังก์ชันตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
window.color = "สีแดง";
ฟังก์ชั่น sayscolor () {
การแจ้งเตือน (this.color);
-
// ข้อผิดพลาดจะถูกรายงานในโหมดที่เข้มงวด หากไม่ได้อยู่ในโหมดที่เข้มงวดมันจะแจ้งให้ "แดง"
saycolor ();
// ข้อผิดพลาดจะถูกรายงานในโหมดที่เข้มงวด หากไม่ได้อยู่ในโหมดที่เข้มงวดมันจะแจ้งให้ "แดง"
saycolor.call (null);
สิ่งนี้จะยังคงไม่ได้กำหนดก่อนที่จะได้รับมอบหมายซึ่งหมายความว่าเมื่อมีการดำเนินการคอนสตรัคเตอร์ข้อยกเว้นจะถูกโยนลงหากไม่มีคำหลักใหม่ที่ชัดเจนมาก่อน
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นบุคคล (ชื่อ) {
this.name = ชื่อ;
-
// จะมีข้อผิดพลาดในโหมดที่เข้มงวด
var me = person ("nicholas");
ในรหัสข้างต้นเนื่องจากไม่มีใหม่มาก่อนสิ่งนี้ในฟังก์ชั่นจะไม่ถูกกำหนด เนื่องจากคุณไม่สามารถตั้งค่าคุณสมบัติสำหรับไม่ได้กำหนดรหัสด้านบนจะส่งข้อผิดพลาด ในสภาพแวดล้อมโหมดที่ไม่ใช่แบบ จำกัด สิ่งนี้ไม่ได้คัดลอกไปยังตัวแปร Window Global โดยค่าเริ่มต้นและผลลัพธ์ของการทำงานจะเป็นการตั้งค่าแอตทริบิวต์ชื่อสำหรับตัวแปรทั่วโลกโดยไม่คาดคิด
ป้องกันการเปลี่ยนชื่อ
เมื่อเขียนโค้ดจำนวนมากคุณสมบัติของวัตถุและพารามิเตอร์ฟังก์ชันจะถูกตั้งค่าเป็นชื่อที่ซ้ำกันโดยไม่ตั้งใจ โหมดที่เข้มงวดจะโยนข้อผิดพลาดอย่างชัดเจนในกรณีนี้
การคัดลอกรหัสมีดังนี้:
// ชื่อตัวแปรซ้ำจะรายงานข้อผิดพลาดในโหมดเข้มงวด
ฟังก์ชั่น dosomething (value1, value2, value1) {
//รหัส
-
// ชื่อแอตทริบิวต์วัตถุที่น่าเบื่อจะรายงานข้อผิดพลาดในโหมดที่เข้มงวด:
var object = {
foo: "bar",
foo: "baz"
-
รหัสข้างต้นจะได้รับการพิจารณาข้อผิดพลาดทางไวยากรณ์ในโหมดที่เข้มงวดและจะช่วยให้คุณได้รับพรอมต์ก่อนการดำเนินการ
Safe Eval ()
แม้ว่าคำสั่ง Eval () จะไม่ถูกลบออกในที่สุด แต่ก็ยังคงดีขึ้นในโหมดที่เข้มงวด การเปลี่ยนแปลงที่ใหญ่ที่สุดคือตัวแปรและการประกาศฟังก์ชั่นที่ดำเนินการใน eval () จะไม่สร้างตัวแปรหรือฟังก์ชั่นที่สอดคล้องกันโดยตรงในขอบเขตปัจจุบันตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
(การทำงาน() {
eval ("var x = 10;");
// ในโหมดที่ไม่ใช่ Strict แจ้งเตือน 10
// ในโหมดที่เข้มงวดข้อยกเว้นจะถูกโยนเพราะ X ไม่ได้กำหนด
การแจ้งเตือน (x);
-
ตัวแปรหรือฟังก์ชั่นใด ๆ ที่สร้างขึ้นระหว่างการดำเนินการของ eval () จะถูกเก็บไว้ใน eval () แต่คุณสามารถรับผลการดำเนินการใน eval () อย่างชัดเจนจากค่าส่งคืนของคำสั่ง eval () ตัวอย่างเช่น:
การคัดลอกรหัสมีดังนี้:
(การทำงาน() {
var result = eval ("var x = 10, y = 20; x + y");
// คำสั่งที่เหลือสามารถทำงานได้อย่างถูกต้องในโหมดเข้มงวดหรือไม่ จำกัด (resulst คือ 30)
การแจ้งเตือน (ผลลัพธ์);
-
โยนข้อยกเว้นเมื่อแก้ไขแอตทริบิวต์แบบอ่านอย่างเดียว
Ecmascript5 ยังแนะนำความสามารถในการตั้งค่าคุณสมบัติเฉพาะของวัตถุให้อ่านอย่างเดียวหรือเพื่อให้วัตถุทั้งหมดไม่ได้แก้ไข อย่างไรก็ตามในโหมดที่ไม่ได้ใช้การพยายามแก้ไขคุณสมบัติแบบอ่านอย่างเดียวจะล้มเหลวอย่างเงียบ ๆ สิ่งนี้น่าจะเกิดขึ้นกับคุณในระหว่างการจัดการกับ API ของเบราว์เซอร์ โหมดที่เข้มงวดจะโยนข้อยกเว้นอย่างชัดเจนในกรณีนี้เตือนคุณว่าไม่อนุญาตให้มีการแก้ไขคุณสมบัตินี้
การคัดลอกรหัสมีดังนี้:
var person = {};
Object.defineProperty (บุคคล "ชื่อ" {
เขียนได้: เท็จ
ค่า: "นิโคลัส"
-
// ในโหมดที่ไม่ได้ใช้ความเงียบล้มเหลวและมีข้อยกเว้นถูกโยนลงในโหมดที่เข้มงวด
person.name = "John";
ในตัวอย่างข้างต้นแอตทริบิวต์ชื่อถูกตั้งค่าเป็นแบบอ่านอย่างเดียว การดำเนินการดัดแปลงแอตทริบิวต์ชื่อในโหมดที่ไม่ใช่ Strict จะไม่ทำให้เกิดข้อผิดพลาด แต่การแก้ไขจะไม่สำเร็จ แต่โหมดที่เข้มงวดจะทำให้เกิดข้อยกเว้นอย่างชัดเจน
หมายเหตุ: ขอแนะนำอย่างยิ่งให้คุณเปิดใช้งานโหมดที่เข้มงวดเมื่อระบุโดยใช้แอตทริบิวต์ ECMASCRIPT ใด ๆ
ใช้อย่างไร?
มันง่ายมากที่จะเปิดใช้งานโหมดที่เข้มงวดในเบราว์เซอร์ที่ทันสมัยเพียงแค่ต้องปรากฏคำสั่งต่อไปนี้ในรหัส JavaScript
"ใช้เข้มงวด";
แม้ว่ารหัสข้างต้นดูเหมือนจะเป็นเพียงสตริงที่ไม่ได้ให้ตัวแปรบางอย่าง แต่จริง ๆ แล้วหมายความว่าเครื่องยนต์ JavaScript เปลี่ยนเป็นโหมดที่เข้มงวด (เบราว์เซอร์ที่ไม่รองรับโหมดที่เข้มงวดจะไม่สนใจรหัสข้างต้นและจะไม่มีผลกระทบใด ๆ ต่อการดำเนินการที่ตามมา) แม้ว่าคุณสามารถใช้คำสั่งนี้กับฟังก์ชั่นทั่วโลกหรือที่นี่เราควรเตือนคุณว่าอย่าเปิดใช้งานโหมดที่เข้มงวดในสภาพแวดล้อมทั่วโลก
การคัดลอกรหัสมีดังนี้:
// โปรดอย่าใช้แบบนี้
"ใช้เข้มงวด";
ฟังก์ชั่น dosomething () {
// ส่วนนี้ของรหัสจะทำงานในโหมดที่เข้มงวด
-
ฟังก์ชั่น dosomethingelse () {
// ส่วนนี้ของรหัสนี้จะทำงานในโหมดที่เข้มงวด
-
แม้ว่ารหัสข้างต้นดูเหมือนจะไม่เป็นปัญหาใหญ่ แต่เมื่อคุณไม่รับผิดชอบในการรักษารหัสทั้งหมดที่แนะนำในหน้าการใช้โหมดที่เข้มงวดด้วยวิธีนี้จะทำให้คุณมีปัญหาที่เกิดจากรหัสบุคคลที่สามที่ไม่ได้เตรียมไว้สำหรับโหมดที่เข้มงวด
ดังนั้นจึงเป็นการดีที่สุดที่จะใช้คำแนะนำที่เปิดใช้งานโหมดที่เข้มงวดในฟังก์ชั่นเช่น:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น dosomething () {
"ใช้เข้มงวด";
// รหัสในฟังก์ชั่นนี้จะทำงานในโหมดที่เข้มงวด
-
ฟังก์ชั่น dosomethingelse () {
// รหัสในฟังก์ชั่นนี้จะไม่ทำงานในโหมดที่เข้มงวด
-
หากคุณต้องการเปิดใช้งานโหมดที่เข้มงวดในฟังก์ชั่นมากกว่าหนึ่งฟังก์ชั่นให้ใช้นิพจน์ฟังก์ชั่นที่ถูกปลุกเร้าทันที (IIFE):
การคัดลอกรหัสมีดังนี้:
(การทำงาน() {
"ใช้เข้มงวด";
ฟังก์ชั่น dosomething () {
// ฟังก์ชั่นนี้ทำงานในโหมดที่เข้มงวด
-
ฟังก์ชั่น dosomethingelse () {
// ฟังก์ชั่นนี้ยังทำงานในโหมดที่เข้มงวด
-
-
สรุปแล้ว
ฉันขอแนะนำอย่างยิ่งให้คุณเปิดใช้งานโหมด JavaScript ที่เข้มงวดนับจากนี้ซึ่งสามารถช่วยให้คุณค้นพบข้อผิดพลาดที่คุณไม่ได้สังเกตในรหัสของคุณ อย่าเปิดใช้งานในสภาพแวดล้อมทั่วโลก แต่คุณสามารถใช้ IIFE ให้มากที่สุด (ดำเนินการนิพจน์ฟังก์ชั่นทันที) เพื่อใช้รูปแบบที่เข้มงวดกับฟังก์ชั่นหลายฟังก์ชั่น ในตอนแรกคุณจะพบกับข้อความแสดงข้อผิดพลาดที่คุณไม่เคยพบมาก่อนซึ่งเป็นเรื่องปกติ เมื่อเปิดใช้งานโหมดที่เข้มงวดตรวจสอบให้แน่ใจว่าได้ทดสอบในเบราว์เซอร์ที่รองรับเพื่อค้นหาปัญหาที่อาจเกิดขึ้นใหม่ อย่าเพิ่มบรรทัด "ใช้อย่างเข้มงวด" ลงในรหัสและสมมติว่ารหัสที่เหลือจะทำงานได้อย่างถูกต้อง สุดท้ายเริ่มเขียนรหัสที่ดีขึ้นในโหมดเข้มงวด
บันทึก:
นี่คือบทสรุปของสถานการณ์การสนับสนุนโหมดที่เข้มงวดของแต่ละเบราว์เซอร์
คุณสามารถทดสอบการสนับสนุนโหมดที่เข้มงวดของเบราว์เซอร์ปัจจุบันในหน้านี้
ข้อดีของโหมดที่เข้มงวด:
ทำให้ JavaScript แข็งแกร่งขึ้น
1. สิ่งนี้ไม่ได้ห่อหุ้มอีกต่อไปและภายใต้โหมดปกตินี่เป็นวัตถุเสมอ
2. ความสนุกผู้เรียกและความสนุกอาร์กุฎจะไม่ลบคุณสมบัติและไม่สามารถตั้งค่าหรือเรียกคืนได้
3. อาร์กิวเมนต์ผู้เรียกเก็บเงินเป็นแอตทริบิวต์ที่ไม่สามารถลบได้และไม่สามารถตั้งค่าหรือเรียกคืนได้
ปูทางสำหรับรุ่น ECMASCRIPT ในอนาคต
1. คำที่สงวนไว้ต่อไปนี้ถูกเพิ่มเข้ามา: ดำเนินการ, อินเทอร์เฟซ, ปล่อย, แพ็คเกจ, ส่วนตัว, ป้องกัน, สาธารณะ, คงที่และผลผลิต
2. การประกาศวิธีการควรวางไว้ที่ด้านหน้าของสคริปต์หรือวิธีการและไม่สามารถวางไว้ในช่วงกลางของข้อความเช่นหรือสำหรับ