2011-12-25 6 views
11

Có cách nào để có một chức năng công khai từ mô-đun truy cập mô-đun riêng biến động không? test1 cho thấy những gì tôi muốn nói với "truy cập tự động", nhưng với các biến côngCó thể truy cập các biến riêng trong mô hình mô-đun động không?

var x = (function(){ 
    var x=0, y=2, z=5; 

    return { 
     toast: 123, 
     test1: function(arg){ 
      return this[arg]; 
     }, 
     test2: function(){ 
      // ?? 
     } 
    }; 
}()); 

console.log(x.test1("toast")); // 123 
console.log(x.test2("y")); // should return 2 

tôi đã kết thúc với việc tạo ra một biến tư nhân duy nhất (một đối tượng) lưu trữ các biến riêng của tôi vì vậy tôi đã có thể truy cập chúng như

rằng
privateVarStore[privateVarName] 

Nhưng có giải pháp nào khác cho điều đó không?

Trả lời

9

DEMO

Yes.

Xin lỗi vì đã thất vọng Adam Rackis nhưng bạn có thể làm điều đó với (các ác) eval:

var x = (function(){ 
    var x=0, y=2, z=5; 

    return { 
     toast: 123, 
     test1: function(arg){ 
      return this[arg]; 
     }, 
     test2: function(a){ 
      return eval(a) 
     } 
    }; 
}()); 

console.log(x.test1("toast")); // 123 
console.log(x.test2("y")); // should return 2 -> does return 2 

Đây là một trong những vài ngoại lệ nơi eval nên được sử dụng.

EDIT, theo Hans B PUFAL gợi ý (comment), bạn có thể và cần xác nhận các tham số trong test2 như sau:

test2: function(a){ 
    return /^[$_a-z][$_a-z0-9]*$/i.test (a) ? eval(a) : undefined; 
} 
+3

Để tránh các sự cố bảo mật, bạn nên thêm xác thực để tham số test2 thực sự là một biến đơn giản: return/^ [$ _ a-z] [$ _ a-z0-9] * $/i.test (a)? eval (a): không xác định; – HBP

+0

@ HansBPUFAL: Ý tưởng tuyệt vời! Tôi chắc chắn sẽ thêm nó – qwertymk

+1

+1, nhưng tôi có thể đề xuất ý tưởng xác thực thay thế: nếu bạn xác định một đối tượng liệt kê các biến riêng tư nào có thể được truy cập thông qua hàm công khai, như 'var accessList = {" x " : true, "y": true}; 'sau đó trong' hàm test2 (a) 'bạn có thể nói' return accessList [a]? eval (a): undefined; '- lợi thế là không chỉ điều này cung cấp bảo mật như những gì chuỗi có thể được chuyển đến eval, nó cho phép bạn xác định các biến thực sự riêng tư khác mà không thể truy cập thông qua' test2() ' . – nnnnnn

7

Không (ít nhất không phải không sử dụng đến eval, theo câu trả lời của qwertymk).

y không phải là tài sản của x (xem xét đặt tên đối tượng này tốt hơn x để tránh nhầm lẫn với biến cục bộ x). y là một biến địa phương mà trên đó các phương pháp của x đã hình thành một kết thúc.

Bất kỳ phương thức nào của x đều có thể truy cập y, nhưng không phải bằng cách nói this.y, mà là truy cập trực tiếp y.

Một lần nữa, y không phải là tài sản của đối tượng của bạn x. Nó chỉ là một biến cục bộ trong hàm đã tạo ra x, do đó gây ra các phương thức của x để tạo thành một kết thúc trên nó.

Vì vậy, để có được test2 trở y, chỉ cần làm:

test2: function(){ 
    return y; 
} 

Để tạo một phương pháp cho phép bạn truy cập các biến riêng, hãy xem xét một cái gì đó như thế này:

var x = (function() { 
    var privateMembers = { x: 0, y: 2, z: 5 }; 

    return { 
     getPrivate: function (name) { 
      return privateMembers[name]; 
     }, 
     toast: 123, 
     test1: function (arg) { 
      return this[arg]; 
     }, 
     test2: function() { 
      // ?? 
     } 
    }; 
})(); 

Và sau đó

alert(x.getPrivate("y")); //alerts 2 

Check-out this fiddle

+0

cách bạn muốn giới thiệu Tim để giải quyết các mã mất tích trong 'test2()' ? – mauris

+0

câu trả lời tuyệt vời, nhưng đó là giải pháp thay thế của tôi (tạo một đối tượng riêng để truy cập các biến riêng của tôi trong chức năng công cộng), tôi đã tự hỏi liệu có cách nào khác (đẹp hơn) để làm điều đó không? –

+0

@Tim - không phải là tôi có thể nghĩ đến. Cá nhân, tôi nghĩ rằng cách trên là đẹp hơn :) –