2015-05-28 11 views
10

Tôi muốn biết nếu có một cách tự nhiên để làm điều này:Một cách tự nhiên của việc thêm chức năng JavaScript tùy chỉnh vào chuỗi phương pháp-cuộc gọi

Object.prototype.chain = function(f) { return f.call(this) } 


function fun1() { 
    doSomethingWithObject(this) 
    return this 
} 

function fun2() { 
    doSomethingElse(this) 
    return this 
} 

someObject 
    .method1('something') 
    .method2() 
    .chain(checkSomething() ? fun1 : fun2) 
    .method3() 

Nhưng tôi không cảm thấy như thay đổi nguyên mẫu của Object . Có cách nào để làm điều này mà không sửa đổi các nguyên mẫu của Objects hoặc các nhà thầu khác mà tôi sử dụng (và đang không phải là nhà phát triển của)

Chỉnh sửa:

tôi cảm thấy tôi không giải thích rất tốt, vì vậy hãy' thêm một số chi tiết:

Điều tôi muốn làm là sử dụng một số API mà tôi không xác định. someObject được định nghĩa như sau, với các phương pháp thể kết nối:

var someObject = { 
    method1: function(val) { 
     // do something 
     return this 
    }, 
    method2: function() { 
     // do something 
     return this 
    }, 
    method3: function() { 
     // do something 
     return this 
    } 
} 

Bây giờ tưởng tượng tôi không thể thay đổi mã này, bởi vì đối tượng này là từ một thư viện, và vì vậy tôi không muốn. Sau đó, hãy tưởng tượng rằng tôi muốn các phương thức chuỗi và một số hàm tùy chỉnh (xem đoạn mã đầu tiên của tôi) cho nhiều đối tượng khác nhau. Điều đơn giản nhất cần làm là đính kèm phương thức chain vào Object.prototype.

Nhưng tôi nghĩ rằng điều đó có thể dẫn đến xung đột trong tương lai. Tôi đang tìm một cách để làm điều tương tự mà không cần chạm vào nguyên mẫu.

+1

ý của bạn là gì cho gọn gàng? –

+0

Tôi có nghĩa là không chạm vào Object.prototype. Tôi đang tìm kiếm một javascript đã có sẵn trên tất cả các đối tượng javascript – niahoo

+0

Vâng, miễn là hàm là một phần của đối tượng gốc ('myObject') và hàm trả về' myObject' ('trả về this', thường) khi hoàn thành nó , bạn có thể gọi một chuỗi chức năng khác. Nếu không tôi sẽ nói - đừng làm thế. Bạn sẽ thấy rằng nó không mang lại bất cứ điều gì hữu ích. –

Trả lời

2

Trình bao bọc là thứ sẽ bao bọc bất kỳ đối tượng nào để làm cho nó tương thích với "chuỗi" và sẽ thêm một phương pháp chuỗi khác cho phép bạn cắm các chức năng bên ngoài và vẫn nhận được chuỗi.

Kiểm tra ví dụ này:

function myObj() { 
    this.state = { 
     a: 1 
    }; 
    this.method1 = function() { 
     console.log("1"); 
    } 
    this.method2 = function() { 
     console.log("2"); 
    } 
    this.method3 = function() { 
     console.log("3"); 
    } 
    this.method4 = function() { 
     console.log(this.state); 
    } 
} 

function objectChainWrapper(obj) { 
    this.chain = function (fn) { 
     fn.call(obj); 
     return this; 
    } 

    for (var prop in obj) { 
     if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') { 
      this[prop] = (function (methodName) { 
       return function() { 
        obj[methodName].call(obj); 
        return this; 
       } 
      }(prop)) 
     } 
    } 
} 

var obj = new myObj(); 
var wrapper = new objectChainWrapper(obj); 
var chainMethod = function(){ console.log('chain') }; 
var chainMethodState = function(){ console.log(this.state) }; 
wrapper.method1().method2().chain(chainMethodState).method3().chain(chainMethod).method4(); 

JSFIDDLE.

+0

Có lý do nào cho trình bao bọc không? Tôi có nghĩa là nếu các chức năng trả về 'này' sau đó bạn sẽ không cần phải sử dụng một wrapper bạn chỉ có thể sử dụng chuỗi thẳng từ chức năng. Vì vậy, cuối cùng chuỗi của bạn sẽ trông giống như: 'myObj.method1(). Method2(). Method3();' Về cơ bản, tất cả các wrapper đang làm là thêm "trả lại này" cho mỗi chức năng anyway. – Jay

+0

@Jay - trình bao bọc lấy một đối tượng và "viết lại" các phương thức của nó để chúng sẽ trả về "điều này" và cho phép chuỗi. Một cách hay để đăng nhập hoặc sửa đổi các phương thức đối tượng của bạn mà không phải sửa đổi các đối tượng của bạn. –

+0

Xin chào; cảm ơn cho anwser của bạn! Khi tôi muốn chèn các chức năng tùy chỉnh trong chuỗi cuộc gọi, tôi không nghĩ rằng mã của bạn có thể cho phép nó. Nhưng thực ra tôi có thể bọc vật thể đầu tiên và thêm phương thức 'chain' vào bộ hồi ký. Tốt điểm – niahoo

5

Tôi rất ngạc nhiên khi không có câu trả lời nào cho điều này.

Có nhiều cách để tự nhiên giới thiệu chuỗi. Tôi thích sử dụng revealing module pattern.

Vì vậy, tôi tạo ra một mô hình cơ bản (Đi trước và chuck này trong chrome lại firefox console)

var Dog = function(name) { 
    var self = this; 
    this.name = name; 


    var core = { 
      getName:function(){ 
       return self.name; 
      } 
     }; 

    this.movement = function(){  //this function will be exposed including its returned functions for chaining  
     console.log(self.name + " is getting restless... "); 

     var jump = function(){ 
      console.log(self.name + " jumps around "); 
      return this //returns the movement scope 
     }; 
     var run = function(){ 
      console.log(self.name + " has decided to run"); 
      return this //returns the movement scope 
     }; 

     return { 
      jump:jump, 
      run:run   
     }; 

    }  
    console.log("A Pup has been born, we shall call him... " + name); 
    return{ 
     movement:self.movement //only .movement is exposed to the outside world 
    }; 
    } 

Bây giờ, tạo một con chó mới sử dụng var p = new Dog("doggyName");

bây giờ, bạn có thể chức năng chuỗi. Hãy thử:

p.movement().jump().run().jump().run(); 

Bạn sẽ nhận được văn bản đăng nhập bảng điều khiển tương ứng với từng chức năng.

Bằng cách trả về phạm vi này sau khi thực hiện chức năng di chuyển của bạn, bạn sẽ hiển thị các hàm bổ sung được trả về trong phạm vi đó (xem các nhận xét trong mã). Sau đó, chúng có thể được xích vào cuối chức năng hiện tại của bạn miễn là chúng nằm trong cùng phạm vi. Điều này cho phép bạn phạm vi các phần cụ thể của mã của bạn. Ví dụ với con chó này, tất cả các chuyển động được scoped để self.movement, bạn có thể có tất cả ăn scoped để self.eat và như vậy

Read up on the revealing module pattern. Mặc dù đây không phải là cách duy nhất để làm điều đó.

+0

Điều này là hữu ích. Quan tâm để biết những cách khác là tốt. – aksappy

+0

Xin chào, cảm ơn câu trả lời của bạn. Tôi đã viết một số chỉnh sửa cho câu hỏi của mình vì tôi nghĩ nó không được viết tốt. Ví dụ của bạn là thú vị, tôi sử dụng mẫu này (nhưng không biết tên, cảm ơn) nhưng nó không cho phép giới thiệu các chức năng tùy chỉnh trong chuỗi – niahoo

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