2015-09-10 20 views
13

Tôi có một lớp đơn giản với một phương thức exec(arg1,..,argn) và tôi muốn có một số phương thức bí danh gọi exec với các giá trị đối số được xác định trước (ví dụ: exec_sync = exec.bind(this, true)).Cách thích hợp để tự động thêm hàm vào các lớp ES6

Sau đây hiện các trick:

class Executor { 
    constructor() { 
    this.exec_sync = this.exec.bind(this, true); 
    } 

    exec(sync, cmd, args/* ... */) { 
    // impl 
    } 
} 

Nhưng Tôi không biết nếu điều này là một ý tưởng tốt, hoặc nếu đây là thành ngữ để ES6.

UDATE:

Trong một ví dụ thực tế cuộc sống tôi có hai vòng lồng nhau với lần lượt 3 và 4 vòng, được sử dụng để tự động thêm một số tổng cộng 12 alias phương thức cho lớp. Nó sẽ là một nhiệm vụ rườm rà để xác định rõ ràng các phương thức bí danh khi bạn thực sự có thể tận dụng lợi thế của JS là một ngôn ngữ lập trình dựa trên nguyên mẫu.

UPDATE 2 - VÍ DỤ:

Giả sử chúng ta có có một khách hàng HTTP đơn giản với một phương pháp request(method, body) và chúng tôi muốn cung cấp phương pháp bí danh cho GET, PUT, vv Nó sẽ trông giống như sau:

class HTTP { 
    constructor() { 
    ['GET', 'PUT', 'POST', 'DEL'].forEach((method) => { 
     this[method] = this.request.bind(this, method); 
    }, this); 
    } 

    request(method, body) { 
    // execute the HTTP request 
    } 
} 
+0

Tại sao không tạo nhiều hàm một cách rõ ràng? 'exec_sync (... args) {return this.exec (true, ... args); } ' – zerkms

+0

@zerkms Tôi nghĩ rằng sẽ rõ ràng hơn những gì lớp học làm. Tôi chỉ quan tâm đến khả năng làm điều gì đó như thế. –

+0

Các lớp ES6 chỉ là cú pháp. Không có gì thay đổi về việc thêm thuộc tính vào một đối tượng trong thời gian chạy. –

Trả lời

19

Giải pháp của bạn là tốt, mặc dù nó sẽ được tốt hơn để tạo ra tất cả các phương pháp đó một lần về mặt kĩ prototype:

['GET', 'PUT', 'POST', 'DEL'].forEach((method) => { 
    Executor.prototype[method] = function (body) { 
    return this.request(method, body) 
    } 
}) 

prototype cách tiếp cận nhanh hơn một chút, bởi vì mã này được thực hiện một lần duy nhất, trong khi mã constructor được thực thi mỗi khi cá thể mới được tạo.

Một ưu điểm khác của prototype trên constructor là nó tương thích với kế thừa lớp. Vì vậy, nếu bạn sẽ mở rộng lớp học của bạn sau đó không có gì sẽ phá vỡ ngay cả khi bạn sẽ xác định lại bất kỳ những phương pháp đó. Bạn có thể sử dụng require('http').METHODS hoặc methods package thay vì mảng động từ HTTP được mã hóa cứng tại đây.

+0

Cảm ơn. các công cụ http nên có được một ví dụ, tôi không sử dụng nó trong mã của tôi :) –

+0

Hãy để chúng tôi [tiếp tục thảo luận này trong trò chuyện] (http://chat.stackoverflow.com/rooms/89272/discussion-between-yan -foto-and-leonid-beschastny) –

+0

Phần lớn ES5 rất wow, cách nào là ES6 của tôi? –

1

tôi không biết về vấn đề này là thành ngữ (vì nó thêm về thiết kế, chứ không phải là ngôn ngữ lập trình riêng của mình), nhưng cá nhân tôi nghĩ rằng việc tạo ra các chức năng rõ ràng sẽ tốt hơn:

exec_sync(...args) { 
    return this.exec(true, ...args); 
} 
+0

Trong ví dụ thực tế, tôi có 2 vòng lồng nhau tương ứng có 3 và 4 mục được sử dụng để tự động thêm tổng cộng 12 mục vào lớp. nó sẽ là một chút cồng kềnh để thêm tất cả mọi thứ bằng tay. –

+0

@YanFoto Tôi sẽ nghĩ về việc chuyển nó sang một lớp riêng biệt thực sự sau đó. – zerkms

+0

Các phương thức đó thực sự và ngữ nghĩa thuộc về lớp. Nếu tôi chuyển chúng sang một lớp riêng biệt, tôi vẫn cần định nghĩa chúng một cách rõ ràng. hoặc tôi đang thiếu một cái gì đó ở đây? –

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