2009-02-28 33 views
18

Nếu bạn muốn sử dụng chức năng toàn cầu và biến động bạn có thể sử dụng:Tôi làm cách nào để truy cập phạm vi địa phương động trong javascript?

window[functionName](window[varName]); 

Có thể làm điều tương tự cho các biến trong phạm vi địa phương?

Mã này hoạt động chính xác nhưng hiện đang sử dụng eval và tôi đang cố gắng nghĩ cách khác để thực hiện.

var test = function(){ 
    //this = window 
    var a, b, c; //private variables 

    var prop = function(name, def){ 
     //this = window 
     eval(name+ ' = ' + (def.toSource() || undefined) + ';');  

     return function(value){ 
      //this = test object 
      if (!value) { 
       return eval('(' + name + ')'); 
      } 
      eval(name + ' = value;') 
      return this; 
     }; 

    }; 

    return { 
     a:prop('a', 1), 
     b:prop('b', 2), 
     c:prop('c', 3), 
     d:function(){ 
      //to show that they are accessible via to methods 
      return [a,b,c]; 
     } 
    }; 
}(); 

>>>test 
Object 
>>>test.prop 
undefined 
>>>test.a 
function() 
>>>test.a() 
1 //returns the default 
>>>test.a(123) 
Object //returns the object 
>>>test.a() 
123 //returns the changed private variable 
>>>test.d() 
[123,2,3] 
+1

tôi nhận được lý do tại sao tôi đã nhầm lẫn bây giờ, đó là bởi vì bạn đang đặt tên các biến abc CŨNG NHƯ tên cho sự trở lại. Bạn nên thay đổi những cái tên đó, đó là điều khiến tôi bối rối. Dù sao, câu trả lời tốt hơn so với tôi đã xuất hiện, vì vậy tôi chỉ sẽ trì hoãn crescentfresh vào thời điểm này. –

+0

@Gothdo Câu hỏi mà bạn liên kết đến là hỏi điều gì đó khác biệt. Các biến mà anh đang cố truy cập là các biến toàn cục. Câu trả lời được chấp nhận cũng sử dụng các biến toàn cầu. Câu hỏi được liên kết phải được thay đổi. – Annan

Trả lời

6

Không, như crescentfresh cho biết. Dưới đây bạn tìm thấy một ví dụ về cách thực hiện mà không có eval, nhưng với một đối tượng riêng bên trong.

var test = function() { 
    var prv={ }; 
    function prop(name, def) { 
    prv[name] = def; 
    return function(value) { 
     // if (!value) is true for 'undefined', 'null', '0', NaN, '' (empty string) and false. 
     // I assume you wanted undefined. If you also want null add: || value===null 
     // Another way is to check arguments.length to get how many parameters was 
     // given to this function when it was called. 
     if (typeof value === "undefined"){ 
     //check if hasOwnProperty so you don't unexpected results from 
     //the objects prototype. 
     return Object.prototype.hasOwnProperty.call(prv,name) ? prv[name] : undefined; 
     } 
     prv[name]=value; 
     return this; 
    } 
    }; 

    return pub = { 
    a:prop('a', 1), 
    b:prop('b', 2), 
    c:prop('c', 3), 
    d:function(){ 
     //to show that they are accessible via two methods 
     //This is a case where 'with' could be used since it only reads from the object. 
     return [prv.a,prv.b,prv.c]; 
    } 
    }; 
}(); 
+0

Điều gì về việc liệt kê các biến cục bộ trong chính hàm đó? Nói cách khác, như eval, nhưng khi bạn không biết người dân địa phương là gì ... – Michael

+0

@Michael Tôi xin lỗi, nhưng tôi không hiểu ý bạn là gì. Bạn có thể đưa ra một ví dụ? Hoặc thậm chí có thể viết câu trả lời của riêng bạn? – some

+0

Tôi không có câu trả lời, và mọi thứ tôi đã đọc dường như cho thấy điều đó là không thể ... biến toàn cầu trong trình duyệt có thể được liệt kê với một cái gì đó như 'for (i in window)'; sẽ tốt đẹp nếu có thể cho người dân địa phương trong một chức năng. – Michael

2

Hy vọng rằng tôi sẽ không quá đơn giản hóa, nhưng những gì về một cái gì đó đơn giản như sử dụng một đối tượng?

var test = { 
    getValue : function(localName){ 
     return this[localName]; 
    }, 
    setValue : function(localName, value){ 
     return this[localName] = value; 
    } 
}; 

>>> test.a = 123 
>>> test.getValue('a') 
123 
>>> test.a 
123 

>>> test.setValue('b', 999) 
999 
>>> test.b 
999 
+0

Nếu bạn định truy cập trực tiếp vào các biến cục bộ của đối tượng, thì điểm của việc định nghĩa một getter hoặc setter là gì? –

+0

Không có. Tôi chỉ cần thêm rằng trong việc sử dụng sẽ giống hệt với ví dụ của Annan. Tôi đồng ý, nó sẽ hoàn toàn ngu ngốc trong thực tế. –

+0

Lý do cho mã là để mô phỏng cách getters và setters làm việc theo một cách trình duyệt chéo. Do đó mã ban đầu của tôi không chính xác (giờ đã được sửa) vì các biến prop() được tạo không có sẵn cho phần còn lại của đối tượng. Cách của bạn cho phép truy cập trực tiếp và thao tác các thuộc tính. – Annan

7

Để trả lời câu hỏi của bạn, không, không có cách nào để thực hiện tra cứu biến động trong phạm vi địa phương mà không sử dụng eval().

Cách thay thế tốt nhất là làm cho "phạm vi" của bạn chỉ là một đối tượng thông thường [nghĩa đen] (ví dụ: "{}") và dán dữ liệu của bạn vào đó.

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