2012-06-01 38 views
11

Tôi muốn sử dụng các hàm làm khóa trong đối tượng javascript. Các công trình sau đây, ít nhất là trong Chrome:Có chức năng các khóa hợp lệ cho thuộc tính đối tượng javascript không?

var registry = {}; 
function Foo(){ }; 
function Bar(){ }; 
registry[Foo] = 42; 
registry[Bar] = 43; 
alert(registry[Foo] + " < " + registry[Bar]); 

Điều này có được bao gồm trong tiêu chuẩn không? Trình duyệt nào được hỗ trợ?

+0

Vâng, làm việc trong Chrome. Vì vậy, nó có thể làm việc trong Safari và Firefox –

+0

tôi nghĩ rằng nó giống như bạn cảnh báo một chức năng, bằng cách nào đó động cơ phân tích nó như là một chuỗi bởi vì nó được cho phép ... Nhưng I'ld nói nó không phải là một ý tưởng tốt, trừ khi bạn bỏ nó như là một chuỗi chính mình trước đây (là điều như vậy có thể tôi tự hỏi) – Sebas

+0

Các phím của bất kỳ loại nào của bất kỳ đối tượng lớp từ điển phải có một hoạt động được xác định rõ ==. Một hoạt động như vậy không thể được định nghĩa cho các hàm (http://en.wikipedia.org/wiki/Rice%27s_theorem). –

Trả lời

14

Tất cả những gì bạn đặt giữa dấu ngoặc vuông được chuyển thành một chuỗi, và điều này xảy ra ngay cả khi bạn đặt một chức năng, một ngày, một regexp ... Vậy đấy, bạn đang thực sự tạo ra một đối tượng như thế này:

var registry = { 
    "function Foo(){ }" : 42, 
    "function Bar(){ }" : 43 
}; 

Đây là hành vi mặc định, nó cũng hoạt động trong IE nếu bạn đang băn khoăn. Nó thực sự được khai thác bởi John Resig trong số famous addEvent function của mình.

+2

Lưu ý rằng các chức năng với các bao đóng khác nhau có thể được chuyển đổi thành cùng một chuỗi và truy cập cùng một thuộc tính. Từ bảng điều khiển nút: > var maker = function (a) {return function() {console.log (a); }; }; > var bb = nhà sản xuất ('bb') > bb() bb > var cc = nhà sản xuất ('dd') > cc() dd > var test = {}; > test [bb] 'AA' = 'AA' > test [bb] 'AA' > bb() bb > kiểm tra { 'function() {console.log (a); } ':' AA '} > kiểm tra [cc] =' DD ' ' DD ' > kiểm tra {' function() {console.log (a); } ':' DD '} > kiểm tra [bb] ' DD ' > kiểm tra [cc] ' DD ' – JoeAndrieu

4

ECMAScript 5.1 - Phần 11.2.1:

Việc sản xuất MemberExpression : MemberExpression [ Expression ] được đánh giá như sau:

  1. Hãy baseReference là kết quả của việc đánh giá MemberExpression.
  2. Hãy để baseValue là GetValue (baseReference).
  3. Hãy để propertyNameReference là kết quả của việc đánh giá Biểu thức.
  4. Hãy để propertyNameValue là GetValue (propertyNameReference).
  5. Gọi CheckObjectCoercible (baseValue).
  6. Cho thuộc tínhNameString là ToString (propertyNameValue).
  7. Nếu sản phẩm cú pháp đang được đánh giá có trong mã chế độ nghiêm ngặt, hãy nghiêm chỉnh đúng, hãy để nghiêm chỉnh là sai.
  8. Trả về giá trị kiểu Tham chiếu có giá trị cơ bản là Giá trị cơ sở và tên được tham chiếu là thuộc tínhNameString và có chế độ nghiêm ngặt cờ là nghiêm ngặt.

Vì vậy, khi sử dụng obj[whatever], whatever được chuyển thành một chuỗi. Đối với một hàm, đây sẽ là một chuỗi chứa mã nguồn của hàm.

Ví dụ:

js> var func = function() { return 'hi'; }; 
js> function helloworld() { return 'hello world'; } 
js> var obj = {}; 
js> obj[func] = 123; 
js> obj[helloworld] = 456; 
js> obj 
({'function() {\n return "hi";\n}':123, 
    'function helloworld() {\n return "hello world";\n}':456 
}) 
Các vấn đề liên quan