2012-03-20 25 views
6

Có cách nào để lấy biến số tên, giống như bạn có thể làm trong .Net với sự phản ánh?
như trong kịch bản này:Nhận tên biến. javascript "reflection"

function(x,y,z) 
{ 
    if (x === 0) 
     logger.log('variable ' + x.reflectedName ' has invalid value ' + x) 
     // logs: 'variable x has invalid value 0) 
    ... 
} 

tôi thấy câu hỏi tương tự mà muốn tên của var bên ngoài của hàm (?!) nhưng không thể tìm thấy câu hỏi này.

(jQuery là một tùy chọn, mặc dù tôi không thể nghĩ làm thế nào nó có thể được thực hiện với nó ...)

+7

Giá trị chỉ ra: bạn không thể lấy tên biến thông qua phản ánh trong .NET. – StriplingWarrior

+0

@StriplingWarrior. bạn có thể với 'Expression' tôi đơn giản hóa nó cho không có .Net phát triển ... – gdoron

+1

tại sao không chỉ đăng nhập tên biến của bạn trong chuỗi? trong ví dụ của bạn, sẽ dễ dàng đặt x vào chuỗi 'console.log ('biến x có giá trị không hợp lệ:', x)' – SpYk3HH

Trả lời

7

Vì bạn đang sử dụng NET làm ví dụ, chúng ta hãy nghiên cứu kỹ một thời gian ngắn vào đó. Trong C#, bạn có thể tạo một hàm mà phải mất một Expression:

void BadArgument<T>(Expression<Func<T>> argExpr) 
{ 
} 

Nhưng để có thể trích xuất các tên biến từ một cuộc gọi đến chức năng này, bạn sẽ phải chắc chắn rằng các cuộc gọi luôn luôn sử dụng chính xác cú pháp đúng (mặc dù không có cách nào để thực thi điều này tại thời điểm biên dịch):

if(x < 0) 
    BadArgument(() => x); 

Vì vậy, nó có thể được thực hiện, nhưng rất mong manh và khá chậm. Về cơ bản, bạn đang tạo ra các hướng dẫn để tạo ra một cây biểu thức toàn bộ dựa trên biểu thức lambda () => x, do đó hàm mà bạn gọi có thể phân tích cú pháp cây biểu thức đó và cố gắng tìm tên của đối số.

Điều này có thể thực hiện được trong javascript không? Chắc chắn rồi!

Trong javascript, đóng cửa được sản xuất thông qua các chức năng nội bộ, vì vậy tương đương với biểu thức lambda trên sẽ là:

function(){return x;} 

Và kể từ javascript là một ngôn ngữ kịch bản, mỗi chức năng tương đương với định nghĩa riêng của mình như một chuỗi. Nói cách khác, gọi .toString() vào chức năng trên sẽ mang lại:

function(){return x;} 

This jsfiddle shows làm thế nào bạn có thể tận dụng điều này trong một chức năng khai thác gỗ theo phong cách. Sau đó bạn được tự do phân tích cú pháp chuỗi hàm kết quả, điều này sẽ chỉ rắc rối hơn một chút so với việc phân tích cú pháp cây biểu thức .NET. Hơn nữa, việc nhận giá trị thực tế của x thậm chí còn dễ dàng hơn trong .NET: bạn chỉ cần call the function!

Nhưng chỉ vì bạn có thể không có nghĩa là bạn nên. Đó là tốt đẹp như một tiệm lừa gee-rít, nhưng khi nói phải xuống với nó, nó không phải là đáng giá:

  • Đó là mong manh: những gì nếu một số nhà phát triển không sử dụng nó đúng đắn và mang đến cho bạn một hàm bạn không thể phân tích cú pháp?
  • Nó không hoạt động với việc rút gọn: hãy tưởng tượng nhận được thông báo biến a có giá trị không chính xác vì hàm được rút gọn của bạn đã thay đổi tên biến của bạn.
  • Nó bổ sung thêm chi phí: ngay cả bộ chỉnh sửa không thể rút ngắn function(){return x;} thành nhỏ hơn "x".
  • Cuối cùng, nó phức tạp. 'nuff nói.
+0

** Tuyệt vời! ** Tôi sẽ không sử dụng nó như bạn đề xuất, nhưng đó là một câu trả lời tuyệt vời ! BTW bạn sẽ sử dụng cụm từ thông dụng nào để nhận 'x' trong hàm'() {return x;} '? – gdoron

+1

@gdoron: Tôi không biết mình có nên sử dụng regex hay không. Về cơ bản bạn chỉ muốn lấy tất cả mọi thứ sau khi "trở về" và trước khi "}", và dải bất kỳ không gian hoặc dấu chấm phẩy, và nói một lời cầu nguyện nhanh chóng rằng mã gọi không ném bạn một quả cầu. – StriplingWarrior

+0

** Chú ý! ** hãy cẩn thận về việc 'minification', khi bạn _minify_ tập tin * .js của bạn có thể thay đổi tên. @gdoron –

6

Bạn không thể. Nhưng kể từ khi bạn đã biết tên biến (kể từ khi bạn phải sử dụng nó để nối nó vào cuối chuỗi), tại sao không chỉ cần gõ nó vào?

tức .:

logger.log('variable x has invalid value '+x); 
+3

Tôi nghĩ rằng ví dụ này là để đơn giản. Tôi cho rằng OP muốn làm điều này trong trường hợp tên biến không được biết trước. Nhưng +1 cho "Bạn không thể." –

+0

Điều gì xảy ra nếu ai đó gọi hàm bằng các biến riêng của họ: 'hàm (a, b, c)', 'x' sẽ vô nghĩa đối với chúng. –

+0

Tôi biết tôi có thể hardcode 'x' nhưng tôi không muốn tot vì lý do của riêng tôi ... – gdoron

6

Thực ra bạn CAN. Đây là một đoạn mã:

function getVarName(v) { 
    for (var key in window) { 
     if (window[key] === v) 
      return key; 
    } 
} 
var testvar = 13142; 
function test(t) { 
    var varName = getVarName(t); 
    // window[varName] -- your variable actualy 
    alert(varName); 
} 
test(testvar); // testvar 

Vấn đề khác là nếu bạn tạo một số lọ chứa cùng một biến. Sau đó, var đầu tiên sẽ được trả về.

+5

'var testvar = 13142; var testvar2 = 13142;' hoặc 'var testvar = true;' hoặc bất kỳ thứ gì là đối tượng sẽ làm hỏng ngày của bạn. Bất cứ điều gì không được xác định trong phạm vi toàn cầu của windows cũng sẽ hủy hoại ngày của bạn. –

-1

Nó rất dễ dàng để có được những tên biến

//This is variable you want to get the name 
var prop; 

var obj = {prop}; 
for(var propName in obj){ 
    alert(propName); 
    break; 
} 

bạn cũng có thể thử trong .

+0

Tôi không nghĩ bạn có câu hỏi. Đọc câu trả lời khác hoặc câu hỏi một lần nữa. Cảm ơn bất kể – gdoron

Các vấn đề liên quan