2012-05-01 45 views
5

Trong JavaScript, bạn có thể soạn đối tượng sử dụng một số loại chức năng extend.Cách tránh xung đột tên khi soạn đối tượng

Ví dụ tôi có thể có một lớp observable đó cho thấy nhiều một tập hợp các phương pháp công cộng (get, push, set, increment, get, vv)

Trong trường hợp này có thể quan sát cũng sẽ xảy ra là một EventEmitter vì vậy nó cũng cho thấy một tập hợp các phương thức công khai khác (emit, on, removeListener, v.v.)

Cả hai lớp này đều có các thuộc tính tiền tố gạch dưới nội bộ lưu trữ trạng thái. Người tổ chức sự kiện sử dụng _events để lưu trữ trình xử lý sự kiện và sử dụng có thể quan sát _state_id để lưu trữ trạng thái và id.

Bây giờ khi tôi tạo ra một mô hình sử dụng thành phần đối tượng như vậy

var Model = extend({}, Observable, { 
    constructor: function() { 
     // Oops, I was supposed to know Observable uses the _state name already 
     this._state = { ... } 
    }, 
    someMethod: function() { ... } 
}) 

Điều này gây ra một vấn đề bởi vì Observable đã sử dụng tài sản _state nội và bây giờ có một cuộc đụng độ tên.

Tôi sẽ xem xét nó xấu xí để chỉ "phải biết" những gì các đối tượng dựa vào những gì nội bộ tài sản cho mixin để làm việc một cách an toàn.

Làm cách nào để tránh trộn lẫn trong hai đối tượng sử dụng cùng tên thuộc tính nội bộ?

Lý tưởng nhất điều này sẽ được giải quyết với tên riêng ES6, nhưng chúng tôi chưa thể thực hiện điều đó và chúng tôi không thể mô phỏng chúng mà không làm mất hiệu suất. Trừ khi bạn có thể cung cấp mô phỏng tên ES6 mà không có hình phạt hiệu suất lớn Tôi không quan tâm đến các giải pháp đó.

Cách khác là sử dụng các bao đóng hoặc bind nhưng sau đó bạn sẽ tái tạo các chức năng cho mỗi trường hợp là một hình phạt hiệu suất đáng kể. Một lựa chọn khác sẽ là không gian tên nội bộ là __eventEmitter_events__observable_state. Đó chỉ là xấu xí và làm giảm xác suất của một xung đột không gian tên, nó không loại bỏ nó.

+0

câu hỏi hay ..! – Alnitak

+0

Nếu bộ nhớ phục vụ, ExtJS giải quyết nó trong đường dẫn tạo đối tượng bằng cách khởi tạo EventEmitter như một thuộc tính treo khỏi Observable, và ủy quyền tất cả các phương thức * public * của EventEmitter thành ràng buộc chức năng sử dụng, trong khi duy trì tất cả trạng thái riêng bên trong EventEmitter đó . Tôi sẽ viết một ví dụ nhưng tôi sẽ AFK ... cho tôi một giờ? – zetlen

+0

@zetlen lưu ý rằng việc ủy ​​quyền của tất cả các phương thức công khai bằng cách sử dụng chức năng ràng buộc có nghĩa là bạn tạo ra một loạt các hàm mới cho mỗi trường hợp quan sát được. như đã đề cập, điều này có hình phạt hiệu suất chính xác như mô phỏng tên riêng. Đây là một giải pháp, nhưng chúng tôi muốn tránh nó vì lý do hiệu suất – Raynos

Trả lời

0

Giải pháp tầm thường là "không gian tên"

var state = "[email protected]~state"; 
var Model = extend({}, Observable, { 
    constructor: function() { 
     // Nice, I used a namespace and don't clash with "[email protected]~state" 
     this[state] = { ... } 
    }, 
    someMethod: function() { ... } 
}) 
Các vấn đề liên quan