ด้วยความนิยมจึงมีหน่วยงานกลางมากำหนดมาตรฐานที่เป็นทางการเพื่อให้มันทำงานเหมือนกันในทุก browser
หน่วยงานนั้นก็คือ ECMA
นั่นคือเหตุผลว่า บางครั้งคนเรียก JavaScript ว่า ECMAScript (ES) นั่นเอง 😮
ECMAScript ผ่านการปรับปรุงมาหลายครั้ง ครั้งสำคัญคือ version ปี 1999 หรือ ES3
browser ส่วนใหญ่ทำ JavaScript ให้มีพฤติกรรมตาม ES3 มากที่สุด
(ECMAScript เป็นมาตรฐานกลาง แต่ browser จะทำตามหรือเปล่านั้นเป็นอีกเรื่องนึง 😕)
มี JavaScript บาง feature ที่ไม่มีใน ES แต่ browser แต่ละเจ้าคิดกันเอง และมีวิธี code แตกต่างจาก browser อื่นๆ จึงเป็นปัญหาต่อมา
การเปลี่ยนแปลงครั้งสำคัญถัดมา คือ ES5 ปี 2009
ES5 เพิ่ม feature ใหม่ๆ มากมาย
บาง feature ก็มีอยู่แล้วในบาง browser แต่กำหนดให้เป็นมาตรฐานมากขึ้น
ปัญหาใหญ่ของ JavaScript คือ feature ที่ไม่ใช่มาตรฐาน บาง browser ก็ใช้ได้ บาง browser ก็ไม่ได้ และถึงแม้จะใช้ได้ก็อาจทำงานไม่เหมือนกัน
เช่น
const myName = "James";นั่นคือ const ไม่ยอมให้เปลี่ยนค่าเริ่มต้น
myName = "Bob !";
myName; // "James"
แต่ !!
บาง browser ยอมให้เปลี่ยน
const myName = "James";JavaScript มีมานาน การจำว่า feature ไหนเป็นมาตรฐานหรือไม่ ควรใช้หรือไม่ เป็นเรื่องน่าปวดหัวของโปรแกรมเมอร์สุดๆ
myName = "Bob !";
myName; // "Bob !"
ด้วยเหตุนี้จึงมีกรณีที่ web app ทำงานถูกใน Chrome แต่พังใน IE (Internet Explorer) บ่อยๆ
ES5 พยายามแก้ปัญหานี้โดยใช้ strict mode
strict mode ไม่ยอมให้มี JavaScript code ที่ใช้ feature ที่เป็นปัญหา
โปรแกรมเมอร์สามารถใช้ strict mode โดยเพิ่ม string พิเศษเข้าไปใน JavaScript code
"use strict";ถ้าอยากใช้กับบาง function ก็ทำได้ตามด้านล่าง
function foo(x) {บาง browser อาจใช้ strict mode ไม่ได้ ซึ่งไม่เป็นปัญหา เพราะมันจะมอง "use strict" เป็น string ธรรมดา
"use strict";
//..
}
browser ที่ใช้ strict mode ได้ จะมี error กับ code ด้านล่าง
function foo(x) {strict mode ไม่ยอมให้ตั้งชื่อตัวแปรว่า arguments เพราะทุก function มีตัวแปร arguments ซ่อนอยู่ การตั้งชื่อซ้ำจะไปทับค่าเดิม ดู ตัวอย่าง
"use strict";
var arguments = []; // error: redefinition of arguments
//..
}
ตำแหน่งของ "use strict" ก็มีประเด็นอยู่ เราควรวางมันใน function หรือข้างนอกดี
คำแนะนำคือไว้ข้างในดีกว่า มาดูเหตุผลกัน 👇
โปรเจคส่วนใหญ่มี js file หลายไฟล์ แต่เวลา deploy ที่ production จะรวมไฟล์ทั้งหมดเป็นไฟล์เดียว เรียกว่า script concatenation เพื่อลดการ request js ไฟล์จาก browser และทำให้ web page โหลดเร็วขึ้น
สมมติมี 2 ไฟล์ file1.js และ file2.js
// file1.jsและ
"use strict";
function foo() {
//...
}
//..
// file2.jsทีนี้ตอนรวมไฟล์ ถ้า file1.js มาก่อน จะเกิด error
// ไม่ใช้ strict mode
function bar() {
var arguments = [];
}
//..
// file1.jsไฟล์ file1.js มาก่อนและใช้ strict mode ทำให้ส่วนของ file2.js เป็น strict mode ไปด้วย ทำให้เกิด error ขึ้น
"use strict";
function foo() {
//...
}
//..
// file2.js
// ไม่ใช้ strict mode
function bar() {
var arguments = []; // error: redefinition of arguments
}
//..
วิธีแก้คือทุกไฟล์ใช้ strict mode ให้หมด
แต่ !! 😬
ถ้าต้องรวมไฟล์ของ third-party library เข้าไปด้วยล่ะ เช่น open-source library
เราไม่สามารถควบคุม third-party code ให้ใช้ strict mode ได้
วิธีแก้คือ ใช้เทคนิค immediately invoked function expression (IIFE)
นั่นคือ ห่อ code ของทั้ง file1.js และ file2.js ด้วย function ด้านล่าง
(function() {
// code file1.js หรือ file2.js
})();
เมื่อรวมไฟล์แล้วจะได้ผลตามด้านล่าง
(function() {เท่านี้โค้ดของ file1.js และ file2.js จะอยู่ในโลกของตัวเองถึงแม้จะรวมเป็นไฟล์เดียวกันแล้วก็ตาม
// file1.js
"use strict";
function foo() {
//...
}
//..
})();
(function() {
// file2.js
// ไม่ใช้ strict mode
function bar() {
var arguments = [];
}
//..
})();
สรุป
- ใช้ strict mode เสมอ
- ห่อโค้ดในแต่ละไฟล์ด้วย IIFE
Enjoy coding !! 😃
บทความน่าสนใจ
Soft Skills 1 : Agile ก็เท่านั้น ถ้าไม่มีใครฟังเราพูด !
No comments:
Post a Comment