2009-06-17 62 views
42

Điều tôi muốn làm là chuyển NAME thành biến được chuyển đến hàm giá trị VALUE của biến đó và chỉ phải chuyển một biến cho hàm. Vì vậy:JavaScript: Nhận giá trị đối số và NAME biến số đã qua

var x = "anything"; 

function showName() { 

} 

showName(x); 

hoặc

showName("x"); 

nào sẽ trở lại: "x = bất cứ điều gì".

Ngay bây giờ, tôi phải làm:

showName("x", x); 

để có được tên và giá trị của biến tôi đi qua trong Lưu ý rằng tôi không quan tâm đến tên của các đối số trong nguyên mẫu của. showName, nhưng tên của biến trong hàm gọi. Ngoài ra, biến có thể là cục bộ, vì vậy tôi không thể sử dụng đối tượng cửa sổ để tìm biến.

+0

http://stackoverflow.com/questions/1007981/how-to-get-function-parameter-names-values-dynamically-from-javascript và http://stackoverflow.com/questions/914968/inspect- các tên-giá trị-của-đối số-trong-định nghĩa-thực thi-of-a-javascript –

+0

@Paulo - các liên kết đó nhận địa chỉ các tên tham số như được định nghĩa trong chữ ký hàm. Câu hỏi này là về việc nhận tên và giá trị của biến được truyền vào hàm. – RedFilter

Trả lời

6
var x = "anything"; 

function showName(s) { 
    alert(s + " = " + eval(s)); 
} 

showName("x"); 

Không được đề xuất, nhưng có.

+1

Điều gì về x = 1; showName (x)? – BaroqueBobcat

+0

@BaroqueBobcat - chức năng trên hoạt động tốt cho tôi. Nếu bạn đang tìm kiếm các trường hợp cạnh, hàm có thể dễ dàng được sửa đổi để xâu chuỗi dữ liệu theo các cách khác nhau dựa trên loại hoặc giá trị. Ví dụ: một mảng trống và chuỗi trống đều hiển thị dưới dạng trống. Bạn có thể muốn xử lý vấn đề này theo cách khác hoặc thêm thông tin bổ sung về dự đoán tốt nhất để nhập. Điểm của ví dụ không phải là chống đạn nhưng để chứng minh rằng một hàm có thể lấy cả tên và giá trị tham số từ một tham số vô hướng. – RedFilter

52

Câu trả lời ngắn gọn là bạn không thể.

Câu trả lời dài hơn, độc ác là bạn có thể có thể có một số vấn đề thực sự. Và nó chỉ hoạt động khi được gọi từ một hàm khác.

có hai thuộc tính thú vị dành cho bạn mà có thể giúp

arguments.callee gọi

cho fn để làm một cái gì đó như thế này:

(function(){ 
    var showMe = function(s){ 
    alert(arguments.callee.caller.toString().match(/showMe\((\S)\)/)[1] + 
    ' = '+ s) 
    } 
    x = 1 
    showMe(x) 
})() 

arguments.callee.caller gì. toString(). match (..) [1] làm là tìm các showMe được gọi trong hàm gọi nó và in nó và giá trị của nó.

Nhưng điều này vẫn còn khá hạn chế vì nó sẽ chỉ nhấn cuộc gọi đầu tiên của showMe (x). Vì vậy, nếu có hai cuộc gọi đến nó, nó sẽ không hoạt động.

Nhưng, thật thú vị khi chơi với những thứ phức tạp này.

+45

+1, kinh tởm và hấp dẫn. –

+0

Điều này sẽ lỗi trên Firefox và Safari khi 'người gọi' là' null' – user1596138

+0

@Jhawins đúng. Có lẽ là một cách hacky xung quanh đó nếu bạn có thể có được một tham chiếu đến chuỗi của nguồn bằng cách nào đó. – BaroqueBobcat

1

Không chắc chắn bạn có thể trực tiếp lấy tên bạn muốn từ JavaScript. thời gian chạy).

Bạn có thể, tuy nhiên, hãy làm điều gì đó hơi khác nhau cho phép chuyển qua các đối số được đặt tên.Tạo một đối tượng nặc danh và vượt qua đó để chức năng của bạn:

function showNames(o) 
{ 
    for(var ix in o) 
    { 
     alert(ix + ":" + o[ix]); 
    } 
} 

var z = { x : "Anything" } 
showNames(z); 
// or 
showNames({ a : "ay", b : "bee", c: "see" }) 

Đối lặp thuộc tính đối tượng, tôi có xu hướng thích một chức năng theo phong cách, như trong:

Array.iteri = function(o, f) 
{ 
    for(var i in o) { f(i, o[i]) } 
} 

function showNames(o) 
{ 
    Array.iteri(o, function(i,v) 
    { 
     alert(i + ": " + v) 
    }); 
} 
showNames({ a : "ay", b : "bee", c: "see" }) 
+0

Không hoàn toàn đúng, JavaScript không phải là một ngôn ngữ biên soạn, không có 'ném đi lúc chạy' – Ally

+1

@ally - Tôi đã nói khái niệm, nhưng hầu hết các công cụ javascript làm (hoặc có thể) biên dịch thành mã trung gian để thực hiện. AFAIK, chỉ Chrome biên dịch trực tiếp javascript sang ngôn ngữ assembly. –

3

Bạn có thể tạo một hash và qua đó in:

var x = {a: 1,b:2} 
function showVars(y) { 
    for (var z in y) { alert(z + " is " + y[z]); } 
} 
showVars(x); 

Điều này không nhất thiết phải hiển thị tên biến, nhưng nó cho phép các cặp khóa-giá trị, có thể nhiều hơn vào điểm bạn cần.

4

tôi đã biết rằng tôi có thể vượt qua trong một đối tượng:

{a:"this is a"} 

nơi một là tên của biến nhưng tôi thực sự muốn chỉ vượt qua trong một biến hoặc tên của một biến (một hoặc "a") và để cho hàm bằng cách nào đó tìm thấy tên của biến và giá trị của nó.

Lý do tôi muốn làm điều này hơi kỳ lạ là tôi đang viết một thói quen in gỡ lỗi. Nếu tôi gọi nó là như thế này:

var x = "some string"; 
say(x); 

hoặc

say("x"); 

Tôi muốn nó in cái gì đó như:

X (string) = some string 

Tôi khá chắc chắn có thể tìm thấy các loại của một biến trôi qua, và vì vậy tôi biết cách in nó, nhưng tôi thực sự muốn cố gắng tránh sự thừa hưởng của việc phải gọi nó như thế này:

say("x", x); 

đó là những gì tôi phải làm bây giờ.

Có vẻ như gần như là hoạt động là câu trả lời của OrbMan. Chắc chắn, evalác, nhưng tôi nghĩ rằng nó ở đây vì nó chỉ dành cho tiện ích gỡ lỗi và sẽ không nằm trong mã được xuất bản. Tôi đã thực hiện một thói quen kiểm tra ít của riêng tôi sử dụng giải pháp rằng:

var x = "this is x"; 

function say(a) { 
    alert(a + " = " + eval(a)); 

} 

say("x"); 

và nó hoạt động nhưng CHỈ NẾU X LÀ GLOBAL. Điều này không hoạt động:

function wrapper() { 

    var x = "this is x"; 
    say("x"); 

} 

Vì vậy, giải pháp này gần, nhưng vì tôi hầu như không sử dụng biến Toàn cầu, điều này sẽ không hoạt động. Darn, nó gần rồi. Những gì tôi nghĩ rằng tôi cần là "gọi theo tên" thay vì "theo giá trị" hoặc "bằng cách tham khảo". Và tôi cần một chức năng sẽ hoạt động cho dù nó đang được gọi từ một chức năng khác hay không.

Vì tôi đã dành nhiều giờ tốt cho bản thân mình, đặt câu hỏi ở đây là một hành động tuyệt vọng, tôi phải kết luận rằng thực sự không có cách nào để làm điều này. Shucks.

Đối với tất cả những người đã trả lời, cảm ơn sự giúp đỡ của bạn.

+0

Không cần thiết cho các biến toàn cầu của riêng bạn cũng như eval, cho cách nhìn vào câu trả lời của tôi. –

1

Mã dưới đây là về điều tốt nhất bạn có thể làm.Thật không may các biến cục bộ trong một hàm là các đặc tính của đối tượng gọi ẩn để chúng không thể được truy cập từ Javascript như cửa sổ [a] trong đó a là thuộc tính của đối tượng cửa sổ.

x = "this is x"; 
var say = function(a) { 
    document.write(a + " = " + window[a]); 
} 
say("x"); 

var wrapper = function() { 
    var x = "this is x"; 
    document.write(x + " = " + eval("x")) 
} 
wrapper() 
2

Đây là những gì tôi sử dụng để gỡ lỗi. Không biến toàn cục, không có eval, không arguments.callee hoặc arguments.caller:

var Helpers = (function() { 
    // ECMAScript 5 strict mode 
    'use strict'; 

    var Module = {}; 

    Module.debug = function() { 
     var i; 

     for (i = 0; i < arguments.length; i++) { 
      console.log(arguments[i] + ':', this[arguments[i]]); 
     } 
    }; 

    Module.SomeObject = function SomeObject() { 
     this.someMember = 1; 
     this.anotherMember = 'Whatever'; 

     Module.debug.call(this, 'someMember', 'anotherMember'); 

     var privateMember = { 
      name: 'Rip Steakface', 
      battleCry: 'Raaaaaaaaahhhhhhhhhrrrrrrrrrg!' 
     }; 

     Module.debug.call(privateMember, 'name', 'battleCry'); 
    }; 

    return Module; 
}()); 

Đối với những người đang tự hỏi tại sao bạn lại muốn làm điều này, nó chỉ là một cách để đăng nhập một cách hiệu quả nhiều biến cùng với tên của họ.

Nếu bạn muốn để có thể đăng nhập thành viên lồng nhau, như trong Module.debug.call(obj, 'hair.fluffiness'), bạn có thể thay đổi chức năng như vậy:

Module.debug = function() { 
    var i, j, props, tmp; 

    for (i = 0; i < arguments.length; i++) { 
     tmp = this; 
     props = arguments[i].split('.'); 

     for (j = 0; j < props.length; j++) { 
      tmp = tmp[props[j]]; 
     } 

     console.log(arguments[i] + ':', tmp); 
    } 
}; 

Thật không may, tôi không thể tìm thấy bất cứ cách nào để đăng nhập một cách hiệu quả nhiều biến tư nhân không phải là thành viên của một đối tượng, ví dụ var roll = 3, value = 4; Module.debug.call(???);

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