Ta nên tránh dùng eval vì một số lý do sau:

  1. Dễ bị tấn công injection.
  2. Không debug được code trong eval.
  3. 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