Học Javascript part 3

Hôm nay mình sẽ đề cập tới 'eval' function, rất hay được sử dụng trong js.

Evaluation Expressions

Giống như các ngôn ngữ thông dịch khác, Javascript có khả năng dịch một đoạn string javascript code và excute để có gía trị output, bằng cách sử dụng hàm eval()

 eval("5+6") // => 11

Dynamic evaluation of strings of source code là 1 tính năng rất mạnh của js, và gặp rất nhiều trong thực tế.

  • Eval():

eval() chỉ chấp nhận 1 đối số. Nếu bạn truyền vào nhiều hơn 1 string, nó đơn giản chỉ return lại chuỗi string đó. Nếu bạn truyền vào một chuỗi string, nó sẽ thử parse chuỗi string như 1 đoạn js code, và throw SyntaxError nếu lỗi. Thưc tế, hàm eval tìm kiếm các giá trị biến và định nghĩa biến mới và function mới theo cách mà local code đang làm. Nếu 1 function định nghĩa 1 local variable x khi đó gọi eval("x"), nó sẽ lấy được giá trị của local variable đó. Nếu gọi eval("x=1"); nó thay đổi giá trị của local variable. Và nếu function gọi eval("var y = 3;"); nó khai báo một local variable y mới. Tương tự 1 function định nghĩa như sau:

   eval("function incre() { return local+1; }");

Nếu bạn gọi eval() từ top-level code, nó sẽ chạy như một global variable hoặc global variable functions.

Chú ý rằng đoạn code string bạn truyền vào eval() phải có nghĩa về mặt cú pháp nếu ko nó sẽ throw SyntaxError, bạn không thể sử dụng nó để paste một đoạn code vào trong 1 function. Nó ko có tác dụng khi viết eval("return;").

  • Global eval():

Dùng eval() để thay đổi local variables là 1 vấn đề khó trong js. Để khắc phục điều đó, trình biên dịch ít tối ưu hơn trong các hàm gọi hàm eval(). Nhưng 1 trình thông dịch js nên làm được gì, tuy nhiên nếu 1 script định nghĩa 1 alias cho eval() và khi đó gọi eval thông qua alias name ? Để đơn giản hoá công việc của trình biên dịch, chuẩn ECMAScript 3 khai báo rằng trình biên bidhcj không dược cho phép điều đó. Nếu hàm eval() được gọi bởi bất khi cái tên nào khác ngoài "eval", nó sẽ throw EvalError.

Trong thực tế, còn xảy ra các tình huống khác nữa. Nếu gọi bằng 1 cái tên khác, hàm eval() sẽ coi như chuỗi string đó là top-level global code. Nó có thể là global variables hoặc global function, hoặc set global variables. Ở ECMAScrip5 thì EvalError bị deprecated và chuẩn hoá behavior của eval(). "Direct eval" là việc hàm eval() được gọi 1 cách trực tiếp. còn lại là "Indirect calll" sử dụng global objects như là biến môi trường (variable environment) không thể read,write, hoặc device local variables hoặc functions.

var geval = eval;
var x = "global", y = "global";
function f() {
    var x = "local";
    eval("x += 'changed';");
    return x;
}
function g() {
    var y = "local";
    geval("y += 'changed';");
    return y;
    // Using another name does a global eval // Two global variables
    // This function does a local eval
    // Define a local variable
    // Direct eval sets local variable // Return changed local variable
    // This function does a global eval // A local variable
    // Indirect eval sets global variable // Return unchanged local variable
}

     console.log(f(), x); // Local variable changed: prints "localchanged global":
     console.log(g(), y); // Global variable changed: prints "local globalchanged":
  • Strict eval():

ECMAScript 5 strict mode bao gồm việc giới hạn còn mạnh hơn khi sử dụng với identifier là "eval". Khi eval() được gọi từ strictmode, hoặc chuỗi string code được evaluated bắt đầu với từ chỉ thị "use strict", khi đó eval() có thể query, set local variables nhưng không thể định nghĩa biến, hoặc function.

Thank u for watching !!! 😄