Giới thiệu hàm Eval trong Javascript
Cú pháp:
eval(string)Eval () là một thuộc tính chức năng của đối tượng toàn cục.
Đối số của hàm eval() là một chuỗi. Nếu chuỗi biểu diễn một biểu thức, eval () sẽ đánh giá biểu thức. Nếu đối số đại diện cho một hoặc nhiều lệnh JavaScript, eval () đánh giá các câu lệnh. Đừng gọi eval() để đánh giá một biểu thức số học; JavaScript đánh giá các biểu thức số học tự động.
Nếu bạn xây dựng một biểu thức số học như một chuỗi, bạn có thể sử dụng eval() để đánh giá nó sau.
Ví dụ, giả sử bạn có một biến x. Bạn có thể trì hoãn đánh giá một biểu thức liên quan đến x bằng cách gán giá trị chuỗi của biểu thức, nói "3 * x 2", cho một biến, và sau đó gọi eval () vào một điểm sau trong mã Javascript của bạn.
Nếu đối số của eval() không phải là một chuỗi, eval() trả về đối số không thay đổi. Trong ví dụ sau, cấu trúc String được chỉ định, và eval () trả về một đối tượng String thay vì đánh giá chuỗi.
eval(new String('2 + 2')); // returns a String object containing "2 + 2"
eval('2 + 2'); // returns 4
Bạn có thể làm việc xung quanh giới hạn này theo cách chung chung bằng cách sử dụng toString().var expression = new String('2 + 2');
eval(expression.toString());
Nếu bạn sử dụng chức năng eval gián tiếp, bằng cách viện dẫn nó qua một tài liệu tham khảo khác với eval, như ECMAScript 5 hoạt động ở phạm vi chung hơn là phạm vi riêng; Điều này có nghĩa là, các khai báo chức năng tạo ra các hàm chung, và mã được đánh giá không có quyền truy cập vào các biến cục bộ trong phạm vi mà nó được gọi.function test() {
var x = 2, y = 4;
console.log(eval('x + y')); // Direct call, uses local scope, result is 6
var geval = eval;
console.log(geval('x + y')); // Indirect call, uses global scope, throws ReferenceError because `x` is undefined
}
Không sử dụng eval không cần thiết!
Eval () là một chức năng nguy hiểm, nó thực hiện mã nó được truyền với các đặc quyền của người gọi. Nếu bạn chạy eval () bằng một chuỗi có thể bị ảnh hưởng bởi một bên độc hại, bạn có thể sẽ chạy mã độc hại trên máy của người dùng với quyền của trang web/tiện ích mở rộng của bạn. Quan trọng hơn, mã của bên thứ ba có thể thấy phạm vi mà trong đó eval () được triệu gọi, điều này có thể dẫn tới các cuộc tấn công có thể xảy ra theo cách mà chức năng tương tự không phải là dễ bị ảnh hưởng.
Eval () thường chậm hơn so với các phương án thay thế vì nó phải gọi trình thông dịch JS, trong khi nhiều cấu trúc khác được tối ưu hóa bởi các động cơ JS hiện đại.
Có những lựa chọn thay thế an toàn hơn (và nhanh hơn) để eval () cho các trường hợp sử dụng phổ biến.
Truy cập thuộc tính thành viên
Bạn không nên sử dụng eval () để chuyển tên thuộc tính thành thuộc tính. Hãy xem xét ví dụ sau đây mà tài sản của đối tượng được truy cập không được biết cho đến khi mã được thực hiện. Điều này có thể được thực hiện với eval:
var obj = { a: 20, b: 30 };
var propName = getPropName(); // returns "a" or "b"
eval( 'var result = obj.' + propName );
Tuy nhiên, eval () không cần thiết ở đây. Trên thực tế, việc sử dụng ở đây không được khuyến khích. Thay vào đó, sử dụng các thuộc tính accessors, nhanh hơn và an toàn hơn nhiều:var obj = { a: 20, b: 30 };
var propName = getPropName(); // returns "a" or "b"
var result = obj[ propName ]; // obj[ "a" ] is the same as obj.a
Bạn thậm chí có thể sử dụng phương pháp này để truy cập các thuộc tính hậu duệ. Sử dụng eval () sẽ giống như sau:var obj = {a: {b: {c: 0}}};
var propPath = getPropPath(); // returns e.g. "a.b.c"
eval( 'var result = obj.' + propPath );
Tránh eval () ở đây có thể được thực hiện bằng cách tách đường dẫn thuộc tính và lặp lại các thuộc tính khác nhau:function getDescendantProp(obj, desc) {
var arr = desc.split('.');
while (arr.length) {
obj = obj[arr.shift()];
}
return obj;
}
var obj = {a: {b: {c: 0}}};
var propPath = getPropPath(); // returns e.g. "a.b.c"
var result = getDescendantProp(obj, propPath);
Thiết lập một thuộc tính tương tự như vậy:function setDescendantProp(obj, desc, value) {
var arr = desc.split('.');
while (arr.length > 1) {
obj = obj[arr.shift()];
}
obj[arr[0]] = value;
}
var obj = {a: {b: {c: 0}}};
var propPath = getPropPath(); // returns e.g. "a.b.c"
var result = setDescendantProp(obj, propPath, 1); // test.a.b.c will now be 1
Sử dụng các chức năng thay vì đánh giá các đoạn mã
JavaScript có các chức năng hạng nhất, có nghĩa là bạn có thể vượt qua các hàm như các đối số cho các API khác, lưu trữ chúng trong biến và các thuộc tính của các đối tượng, v.v ... Nhiều API DOM được thiết kế với điều này trong tâm trí, do đó bạn có thể (và nên) viết:
// instead of setTimeout(" ... ", 1000) use:
setTimeout(function() { ... }, 1000);
// instead of elt.setAttribute("onclick", "...") use:
elt.addEventListener('click', function() { ... } , false);
Closures cũng rất hữu ích như là một cách để tạo ra các tham số mà không cần nối dây.Phân tách cú pháp JSON (chuyển đổi các chuỗi thành các đối tượng JavaScript)
Nếu chuỗi bạn đang gọi eval () trên chứa dữ liệu (ví dụ: mảng "[1, 2, 3]"), ngược lại với mã, bạn nên xem xét chuyển sang JSON, cho phép chuỗi sử dụng Tập hợp con của cú pháp JavaScript để biểu diễn dữ liệu. Xem thêm Tải về JSON và JavaScript trong phần mở rộng.
Lưu ý rằng vì cú pháp JSON bị hạn chế so với cú pháp JavaScript, nhiều văn bản JavaScript hợp lệ sẽ không phân tích cú pháp là JSON. Ví dụ: dấu phẩy sau không được phép trong JSON và tên thuộc tính (khóa) trong các ký tự đối tượng phải được bao gồm trong dấu ngoặc kép. Đảm bảo sử dụng một trình tạo mã JSON để tạo chuỗi sau đó được phân tích cú pháp dưới dạng JSON.
Truyền dữ liệu thay vì mã
Ví dụ: tiện ích được thiết kế để cạo nội dung của các trang web có thể có các quy tắc cào được xác định trong XPath thay vì mã JavaScript.
Chạy mã với các đặc quyền giới hạn
Nếu bạn phải chạy mã, hãy xem xét chạy nó với các đặc quyền giảm. Lời khuyên này áp dụng chủ yếu cho các ứng dụng mở rộng và XUL, có thể sử dụng Components.utils.evalInSandbox cho việc này.
Ví dụ
Sử dụng eval
Trong đoạn code sau, cả hai câu lệnh chứa eval () trả về 42. Đầu tiên đánh giá chuỗi "x + y + 1"; Phần thứ hai đánh giá chuỗi "42".
var x = 2;
var y = 39;
var z = '42';
eval('x + y + 1'); // returns 42
eval(z); // returns 42
Sử dụng eval để đánh giá một chuỗi các câu lệnh JavaScript
Ví dụ sau sử dụng eval () để đánh giá chuỗi str. Chuỗi này bao gồm các câu lệnh JavaScript mở hộp thoại cảnh báo và chỉ định z một giá trị là 42 nếu x là năm và gán 0 cho zotherwise. Khi câu lệnh thứ hai được thực hiện, eval () sẽ làm cho các câu lệnh này được thực hiện, và nó cũng sẽ đánh giá tập hợp các câu lệnh và trả về giá trị được gán cho z.
var x = 5;
var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0;";
console.log('z is ', eval(str));
Biểu thức cuối cùng được đánh giá
Eval () trả về giá trị của biểu thức cuối cùng được đánh giá.
var str = 'if ( a ) { 1 + 1; } else { 1 + 2; }';
var a = true;
var b = eval(str); // returns 2
console.log('b is : ' + b);
a = false;
b = eval(str); // returns 3
console.log('b is : ' + b);
Eval như là một chức năng xác định chuỗi đòi hỏi "(" and ")" như tiền tố và hậu tố
출장안마
var fctStr1 = 'function a() {}'
var fctStr2 = '(function a() {})'
var fct1 = eval(fctStr1) // return undefined
var fct2 = eval(fctStr2) // return a function
0 nhận xét:
Lưu ý: Chỉ thành viên của blog này mới được đăng nhận xét.