2010-05-03 59 views
12

Tôi có một chút mã JavaScript được chỉ định trong tệp cấu hình ở phía máy chủ. Vì tôi không thể chỉ định một hàm JavaScript trong ngôn ngữ cấu hình (Lua), tôi có nó như một chuỗi. Các máy chủ trả về chuỗi trong một số JSON và tôi có khách hàng giải thích nó bằng cách sử dụng chức năng dọn dẹp:JavaScript eval() "lỗi cú pháp" khi phân tích chuỗi hàm

parse_fields = function(fields) { 
    for (var i = 0; i < fields.length; ++i) { 
     if (fields[i].sortType) { 
      sort_string = fields[i].sortType; 
      fields[i].sortType = eval(sort_string); 
     } 
     return fields; 
    } 
}; 

Vì vậy, về cơ bản nó chỉ đánh giá sortType nếu nó tồn tại. Vấn đề là Firebug đang báo cáo "Lỗi cú pháp" trên dòng eval(). Khi tôi chạy các bước tương tự trên giao diện điều khiển Firebug, nó hoạt động không có vấn đề gì và tôi có thể thực thi hàm như tôi mong đợi. Tôi đã thử một số biến thể khác nhau: window.eval thay vì đồng bằng eval, lưu trữ sortType như tôi đã thực hiện ở trên và thử các biến thể nhỏ cho chuỗi.

Giá trị mẫu là fields[i].sortType"function(value) { return Math.abs(value); }". Đây là thử nghiệm tôi đã làm trong Firebug console:

>>> sort_string 
"function(value) { return Math.abs(value); }" 
>>> eval(sort_string) 
function() 
>>> eval(sort_string)(-1) 
1 

và lỗi chính nó trong Firebug:

syntax error 
[Break on this error] function(value) { return Math.abs(value); } 

Bit cuối cùng có thể có liên quan là điều này là tất cả được bọc trong một Ext JS onReady() chức năng, với sự thay đổi không gian tên Ext.ns ở trên cùng. Nhưng tôi giả định rằng window.eval sẽ gọi toàn cầu là eval, bất kể bất kỳ có thể nào eval trong các không gian tên cụ thể hơn.

Bất kỳ ý tưởng nào được đánh giá cao.

+3

Lưu ý rằng trình duyệt IE có thể chức năng không eval. – SLaks

+0

thử 'var foo = function (value) {...}' –

+0

@SLaks: 'eval' hoạt động tốt cho tôi trong IE đối với chuỗi ở trên, không có lỗi ... cũng như' eval ("a = function () {return 'b';} ")' - bạn có thể làm rõ ý bạn muốn nói gì không? –

Trả lời

37

Để làm những gì bạn muốn, quấn chuỗi của bạn trong ngoặc đơn:

a = "function(value) { return Math.abs(value);}"; 
b = eval("("+a+")"); 
b(-1); 
+2

Đúng, đã hoạt động. Tại sao các dấu ngoặc đơn được yêu cầu khi Firefox thực hiện mã bên ngoài giao diện Firebug, nhưng không bắt buộc khi sử dụng giao diện điều khiển Firebug? –

+0

Tôi, đối với một, không thể làm cho nó hoạt động mà không có niềng răng ngay cả trong giao diện điều khiển Firebug. Tôi không biết tại sao nó lại phù hợp với bạn. Bạn đang sử dụng phiên bản Firebug nào? – Jasper

+1

@Kenny Peng: Tôi nhớ tự hỏi bản thân mình một lần và tìm thấy câu trả lời này cho một câu hỏi tương tự: http://stackoverflow.com/questions/964397/why-does-javascripts-eval-need-parentheses-to-eval-json- dữ liệu/964437 # 964437. Đây là suy nghĩ đầu tiên của tôi khi tôi nhìn thấy câu hỏi, +1 với @jhurshman cho câu trả lời của anh ấy. –

4

Các dấu ngoặc đơn được yêu cầu bởi vì họ buộc các điều bên trong chúng được đánh giá trong một bối cảnh biểu, nơi nó phải là một chức năng thể hiện .

Không có dấu ngoặc đơn, thay vào đó có thể là hàm khai báo và dường như nó đôi khi được phân tích cú pháp theo cách này - đây có thể là nguồn gốc của hành vi kỳ lạ/không nhất quán mà bạn mô tả.

Hãy so sánh khai báo hàm này:

function foo(arg) {} 

với điều này chức năng biểu hiện:

var funcExpr = function foo(arg) {}; 

Nó cũng có được một chức năng thể hiện nếu nó không có một cái tên. Khai báo hàm yêu cầu tên.

Vì vậy, đây không phải là một tuyên bố hợp lệ, vì nó thiếu tên của nó:

function (arg) {} 

nhưng điều này là đúng đắn, mang tính chất chức năng biểu hiện:

var funcExpr = function(arg) {}; 
Các vấn đề liên quan