2009-07-13 38 views
8

Về cơ bản đây là câu hỏi về cách truy cập trình xử lý phạm vi cục bộ. Tôi cố gắng để đạt được một cái gì đó tương tự cho định nghĩa biến toàn cầu như:Biến cục bộ Javascript khai báo

window['newObject'] = "some string"; 
alert(newObject); 

nhưng đối với phạm vi địa phương. Ngay bây giờ chỉ có giải pháp tôi có là sử dụng evals:

eval("var newObject='some string'"); 

Nhưng điều này thực sự là giải pháp xấu xí ... Tốt nhất sẽ như thế nào sử dụng một số tài liệu tham khảo để phạm vi địa phương như trong một cửa sổ [] giải pháp, nhưng tôi chưa bao giờ nghe của bất kỳ tham chiếu đến phạm vi địa phương ... Bất kỳ ý tưởng?

Ví dụ tại đây:

function x(arg) 
{ 
    localScope[arg.name]=arg.value; 
    alert(sex); 
} 

x({name:"sex", value:"Male"}); 
+0

tôi nhìn thấy, bạn có nghĩa là có một javascript tương đương với "biến biến" của php. http://www.php.net/manual/en/language.variables.variable.php –

+0

Bản sao có thể có của [JavaScript: Nhận biến cục bộ theo chuỗi tên] (http://stackoverflow.com/questions/1920867/javascript -get-local-variable-dynamic-by-name-string) –

Trả lời

1

Okey Tôi tìm thấy câu hỏi liên quan đang nói về những gì tôi cần ...

How can I access local scope dynamically in javascript?

Tôi chỉ nhớ rằng trong ECMA 262 chỉ là một cách để thêm các biến động địa phương để phạm vi sử dụng "với" tuyên bố (và eval tất nhiên), đây là giải pháp:

var x=function(obj) 
{ 

    with(obj) 
    { 
     alert(someObj); 
    } 
} 
alert(typeof someObj); 


x ({someObj:"yea"}) ; 

alert(typeof someObj); 
+1

Điều duy nhất khối 'with' cung cấp cho bạn, là bạn không phải viết' alert (obj.someObj) '.Với chi phí thêm ba dòng mã bổ sung. –

+1

"với" là một điều xấu để sử dụng. Xem http://www.yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/ và https://developer.mozilla.org/En/Core_JavaScript_1.5_Guide/Object_Manipulation_Statements –

+0

Có - cả hai những vấn đề đó: khả năng đọc và truy cập phạm vi cục bộ chậm hơn một chút là hợp lý với hệ thống templatings mà tôi cần tạo. – Wilq32

1

tôi phải mất một cái gì đó. Làm thế nào là những gì bạn muốn khác với chỉ làm:

var newObject = 'some string'; 

? (OP đã làm rõ câu hỏi)

Tôi không nghĩ rằng có một cách để làm những gì bạn đang yêu cầu. Sử dụng các thành viên của một đối tượng địa phương, ví dụ:

function doSomething(name, value) 
{ 
    var X = {}; 
    X[name] = value; 
    if (X.foo == 26) 
    alert("you apparently just called doSomething('foo',26)"); 
} 

Nếu bạn chọn biến 1 ký tự như $ hoặc X, bạn sẽ cố gắng sử dụng eval hoặc làm điều lạ.

+0

Có - Tôi muốn làm điều đó tự động coresponding dữ liệu tôi nhận được để chức năng này. – Wilq32

+0

Ý tôi là - có bạn bỏ lỡ điều gì đó ở đó. Tôi cần một biến địa phương xác định;) – Wilq32

0

Câu hỏi thú vị, không bao giờ nghĩ về điều gì đó như thế này. Nhưng usecase là gì?

Lý do bạn muốn làm điều gì đó như thế này, là nếu bạn không biết tên của biến. Nhưng sau đó trong trường hợp đó, cách duy nhất để truy cập biến một lần nữa sẽ sử dụng cùng một đối tượng tham chiếu. I E. bạn chỉ có thể sử dụng bất kỳ đối tượng cũ nào để lưu trữ dữ liệu.

Đọc từ một đối tượng tham chiếu như vậy sẽ rất thú vị cho mục đích gỡ lỗi, nhưng tôi không hiểu tại sao bạn muốn ghi vào đó.

Edit:

Ví dụ bạn được đăng không thuyết phục tôi về sự cần thiết để truy cập vào phạm vi địa phương, vì bạn vẫn có tên sex cứng mã hoá trong cảnh báo. Điều này có thể được triển khai dưới dạng:

function x(arg) 
{ 
    container = {}; 
    container[arg.name] = arg.value; 
    alert(container.sex); 
} 

Bạn có thể giải thích thêm về ví dụ này không?

+0

Ví dụ không phải là để thuyết phục rằng điều này là cần thiết. Tôi làm việc trên hệ thống mẫu và giải thích lý do tại sao tôi cần điều đó sẽ mất rất nhiều thời gian và sẽ thực sự phức tạp :) – Wilq32

+0

Tôi chỉ cần có thể gọi (alert (sex)) nơi tên biến có thể được lấy từ nguồn bên ngoài;) – Wilq32

+0

Ah, vậy điều gì xảy ra là hệ thống mẫu của bạn không cho phép các dấu chấm trong hộp cảnh báo? ;-) Nếu không, 'alert (obj.someObj)' chỉ hoạt động. –

1

Tại sao không tạo đối tượng trong phạm vi cục bộ và sau đó sử dụng đối tượng đó làm vùng chứa cho bất kỳ biến nào bạn muốn tạo động?

function x(arg) 
{ 
    var localSpace = {}; 
    localSpace[arg.name] = arg.value; 
} 
+0

Nhưng tôi cần chỉ có thể tham khảo phần tử dưới dạng tên, chứ không phải với localSpace [name] trước mỗi biến ... – Wilq32

+0

tại sao lại là yêu cầu? –

+0

vì bên thứ ba muốn tham khảo các mẫu với giá trị riêng của họ từ phạm vi địa phương ... giải thích điều này thực sự phức tạp, nhưng tôi có thể chắc chắn rằng không có cách nào khác để làm điều này chỉ bằng cách mở rộng phạm vi cục bộ (hoặc toàn cục) nhưng với quyền truy cập vào các biến dài hơn). – Wilq32

-1

Tôi không hoàn toàn chắc chắn rằng tôi hiểu câu hỏi của bạn. Khi tạo một lớp x, tôi thường làm điều này:

function x(args) { 
    var _self = this; 

    _self.PriviledgedMethod(a) { 
     // some code 
    } 

    function privateMethod(a) { 
     // some code 
    } 
} 

var newObject = new x(args); 

Bạn có thể tiếp tục truy cập _self và arg vì nó bị đóng bởi các chức năng chứa.

+0

tránh đánh giá bằng mọi giá (đôi khi bạn không thể). bằng cách tránh nó, bạn sẽ cho phép khả năng khai thác tốt hơn. –

+0

Tôi hỏi điều gì đó hoàn toàn khác biệt - cách tạo động một biến trong phạm vi địa phương - bạn có thể nhập cảnh báo (sex) trong đó 'sex' được tạo động trong phạm vi địa phương – Wilq32

1

Bạn có thể thử các tên đối số lừa
EDIT: Đây không phải là cross trình duyệt

function x({sex:sex, height:height}) { 
    alert(sex); 
    alert(height); 
} 

x({ sex: 'male', height: 'short' }); 
x({ height: 'medium', sex: 'female' }); 

// male 
// short 
// female 
// medium 
+0

hấp dẫn ... là ECMAscript này hay chỉ là một phương ngữ cụ thể ? (ví dụ: Spidermonkey vì nó dường như hoạt động với Spidermonkey 1.7) –

+0

Thú vị nhất .. Tôi thêm +1 :) – Wilq32

+0

Đây là một phần của JS1.7 và được gọi là gán destructuring. Bạn có thể đơn giản hóa khai báo hàm này thành: function x ({sex, height}) {...} – Prestaul

6

gì bạn đang tìm kiếm được gọi là đối tượng gọi. Nhưng theo số this, bạn không thể truy cập trực tiếp, vì vậy bạn không may mắn.

+0

Tôi chưa bao giờ nghe thuật ngữ _call object_ trước đây, nhưng liên kết bạn cung cấp là hữu ích . Nó trông giống như một chi tiết triển khai JavaScript để mô tả phạm vi địa phương của một hàm (có thể thoát khỏi phạm vi "cục bộ" bằng cách bị bắt trong một đóng). Tuy nhiên, tôi không nghĩ rằng điều này có liên quan nhiều đến câu hỏi ban đầu. –

+0

Suy nghĩ thứ hai, nếu bạn _could_ trực tiếp truy cập vào chi tiết triển khai đó, nó sẽ có liên quan đến câu hỏi, vì vậy bạn đang ở trong khía cạnh đó. –

+0

Phải; nếu bạn có thể, bạn có thể làm những gì anh ta hỏi: "localScope [name] = value;" –

1

Không chắc chắn những gì bạn cần chính xác, nhưng đây là 2 xu của tôi.

Cách duy nhất để tạo động vars trong hàm hiện có là phương pháp eval bạn đã đề cập.

Một tùy chọn khác (được đề cập bởi những người khác) là chức năng của bạn mất một bản đồ ngữ cảnh, và các mẫu truy cập nó bằng ký hiệu dấu chấm (context.var1)

gợi ý cuối cùng của tôi là các nhà xây dựng chức năng. Nhưng tôi có cảm giác rằng đây có thể là thứ bạn đang tìm kiếm. (Lưu ý rằng các nhà xây dựng chức năng bị những vấn đề tương tự như một cuộc gọi eval)

var arg1 = "first"; 
var arg2 = "last"; 

// This is the body of the function that you want to execute with first 
// and last as local variables. It would come from your template 
var functionBody = "alert(first + ' ' + last)"; 

var myCustomFun = new Function(arg1, arg2, functionBody); 

myCustomFun("Mark", "Brown"); // brings up and alert saying "Mark Brown"; 

Hy vọng nó giúp

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