2013-05-03 20 views
18

Tôi đã chạy qua một JavaScript library triển khai một trình duyệt chéo WeakMap trong ES5. (WeakMap được dự kiến ​​cho ES6.)Triển khai WeakMap trong EcmaScript5?

Làm thế nào điều này có thể hoạt động mà không có hỗ trợ trong chính ngôn ngữ JavaScript?

Edit: Chỉ cần được rõ ràng, tôi đề cập đến một bản đồ Yếu, không một bản đồ thông thường. Tôi đã thử nghiệm dự án này bằng cách sử dụng trình thu thập của Chrome và các khóa không được tổ chức bởi các tham chiếu mạnh mẽ. Họ nhận được GC'ed mà không cần phải loại bỏ chúng khỏi WeakMap.

+3

Cân nhắc nghiên cứu mã nguồn. –

+3

@squint Nó đang làm một cái gì đó khá sâu-- Tôi không thể tìm ra cách nó không giữ một tham chiếu mạnh mẽ đến các phím. Ví dụ, nó không sử dụng các mảng. – paleozogt

+3

WeakMaps là một tính năng ES6 cho phép bạn kết hợp dữ liệu với một đối tượng, nhưng vẫn để dữ liệu đó được thu thập rác khi đối tượng -OR- bản thân WeakMap chính là rác được thu thập. Không thể thực hiện cả hai điều này mà không cần hỗ trợ ngôn ngữ. Hầu hết các bản đồ WeakMap bỏ qua phần về việc cho phép dữ liệu được GC'd khi bản thân WeakMap là GC'd. – AgentME

Trả lời

26

Tôi mất một lúc để bẻ mã, nhưng sau đó nó đánh vào tôi: chính khóa được sử dụng để lưu trữ một tham chiếu đến giá trị.

Ví dụ, một số lớp vào set

defProp(obj, globalID, { value: store }); 

nơi defProp đã được định nghĩa là Object.defineProperty, obj là chìa khóa, globalID là một guid và store là một đối tượng lưu trữ có chứa các giá trị.

Sau đó xuống trong get nó ngước lên giá trị với

obj[globalID];

Đây là rất thông minh. WeakMap không thực sự chứa một tham chiếu đến bất cứ điều gì (yếu hoặc cách khác) - nó chỉ thiết lập một chính sách của nơi để bí mật lưu trữ giá trị. Việc sử dụng Object.defineProperty có nghĩa là bạn sẽ không vô tình khám phá bộ nhớ giá trị-- bạn phải biết hướng dẫn ma thuật để tìm kiếm nó.

Vì khóa trực tiếp đề cập đến giá trị (và Bản đồ Weak không đề cập đến nó), khi tất cả các tham chiếu đến khóa bị mất, nó sẽ được GC như bình thường.

+0

Nếu 'obj' là khóa WeakMap và' globalID' được định nghĩa trên 'obj', tôi tự hỏi tại sao' globalID' không hiển thị khi sử dụng 'Object.getOwnPropertyNames()'. –

+2

tôi đã tự hỏi như vậy; quá xấu lib là cho đến nay nó là của riêng đằng sau là hầu như không đọc được. có phải là một lời giải thích đơn giản hơn ... – dandavis

+0

tìm ra: các cheats lib: nó tái định nghĩa Object.getOwnPropertyNames(). boo cho bước vào chức năng bản địa hiện có. – dandavis