2012-10-02 40 views
6

Nếu tôi có một chức năng như thế này:Trọng một chức năng mà không cần loại bỏ các thuộc tính tĩnh

function a() { 
    console.log('a'); 
} 

và sau đó gán thuộc tính tĩnh như thế này:

a.static = 'foo'; 

Nhưng nói rằng tôi muốn ghi đè lên các chức năng với một chức năng khác như sau:

var old = a; 

a = function() { 
    console.log('new'); 
    old.call(this); 
}; 

a.static // undefined 

Vì tôi đã gán một chức năng mới cho a, tính chất tĩnh của nó bị mất. Có cách nào gọn gàng để giữ các thuộc tính tĩnh mà không lặp lại và sao chép chúng theo cách thủ công không?

Cập nhật:

Dưới đây là một kịch bản thế giới thực: Trong plugins Bootstrap jQuery, tác giả gán giá trị mặc định cho chức năng sở hữu như thế này:

$.fn.modal = function() { 
    // some code 
}; 

$.fn.modal.defaults = { // some object }; 

Vì vậy, nếu tôi muốn "mở rộng" các nguyên mẫu tôi thường làm:

var old = $.fn.modal; 

$.fn.modal = function() { 
    // do my thing 
    old.apply(this, arguments); 
} 

Nhưng điều đó sẽ làm cho

$.fn.modal.defaults === undefined 

Điều này sẽ phá vỡ chức năng, vì mặc định bị mất. Tôi đã tự hỏi nếu có một cách lén lút trong javascript để thay đổi chỉ có chức năng mà không làm mất các thuộc tính tĩnh.

+1

Tôi có thể hỏi việc sử dụng phương pháp này là gì không? Nó trông rất lộn xộn. – Christoph

+0

Tôi hỏi vì trong các plugin jQuery bootstrap, tác giả gán các giá trị mặc định tĩnh làm đối tượng được gắn vào mẫu thử nghiệm. Vì vậy, nếu tôi muốn mở rộng nó, tôi mất các giá trị mặc định (và có thể là các thuộc tính khác) được đính kèm. Ngoài ra, bởi vì tôi tò mò nếu có một cách để chỉ thay đổi chức năng, không phải là thuộc tính tĩnh. – David

Trả lời

3

Không, bạn không thể thực hiện việc này. Thay thế đối tượng (hàm) luôn luôn lấy bất kỳ thuộc tính nào với nó.

Có hai giải pháp ở đây và cả hai đều liên quan đến việc chuyển các thuộc tính từ đối tượng cũ sang đối tượng mới.

The (recommended) Cách tiếp cận thứ nhất là để sao chép các thuộc tính, mà có thể được thực hiện thuận tiện với $.extend:

$.fn.plugin = $.extend(function() { ... }, $.fn.plugin); 

Lựa chọn thứ hai sẽ được tự động thiết lập các nguyên mẫu của hàm mới là chức năng cũ . Ví dụ: trong một số trình duyệt, thao tác này sẽ hoạt động:

var f = function() { ... }; 
f.__proto__ = $.fn.plugin; 
$.fn.plugin = f; 

Tuy nhiên điều này không chuẩn và có thể dẫn đến biến chứng; đừng làm thế.

+0

Tôi không nghĩ đến '$ .extend' như một cách để sao chép các thuộc tính của hàm, nhưng nó hoạt động tốt. Cảm ơn – David

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