Lương tri là Chúa trong mỗi con người. Conscience is God present in man.
Victor Hugo
Ta nên tránh dùng eval vì một số lý do sau:
- Dễ bị tấn công injection.
- Không debug được code trong eval.
- Hiệu năng khi chạy code trong eval.
Có 2 cách gọi eval là gọi trực tiếp(Direct call) và gọi gián tiếp(Indirect call)
- Direct call là gọi trực tiếp bằng cách gọi
eval(...your code...) - Indirect call là gọi gián tiếp thông qua một biến trung gian(xem VD phía dưới)
Xét ví dụ sau:
x = 10;
(function foo() {
var x = 20;
(function bar(){
var x = 30;
eval("console.log(1, x)")
var indirectEval = eval;
indirectEval("console.log(2, x)");
("indirect", eval)("console.log(3, x);");
var window = 100;
eval("console.log(4, window);");
indirectEval("console.log(5, window);");
})();
})();
this.eval("var y = 20;");
console.log(6, y);
Câu lệnh eval ở dòng 7 và 15 là direct call, còn câu lệnh ở dòng 10, 12, 16, 21 là indirect call
Indirect call sẽ luôn truy xuất tới biến ở global (không phải là biến ở scope hiện tại x = 30 hay scope cha x = 20)
Direct call sẽ truy xuất tới biến theo lexical scope như gọi hàm thông thường (từ scope hiện tại lên dần)
Đoạn code trên sẽ cho ra kết quả:
1 30
2 10
3 10
4 100
5 Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
6 20
Link tham khảo:
http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/#indirect-eval-call
Comments
