2011-03-20 54 views
4

我正在創建一個JavaScript庫。我一直在試圖實施鏈接。在庫中實現Javascript鏈接的最佳方法

0:我第一次來到了:

function V(p) { 
    return { 
    add : function(addend) { return V(p + addend); }, 
    sub : function(subtra) { return V(p - subtra); }, 
    }; 
} 

使用這種方法,我可以鏈很容易:

V(3).add(7).sub(5) // V(5) 

不幸的是,結果總是一個包布V()函數,我我無法以這種方式提取結果值。所以我想了一下這個問題,並提出了兩個半解決方案。

1:傳遞標誌的最後一個方法

function V(p, flag) { 
    if(flag) 
    return p; 
    else 
    return { 
     add : function(addend, flag) { return V(p + addend, flag); }, 
     sub : function(subtra, flag) { return V(p - subtra, flag); } 
    }; 
} 

使用這種方法,我可以通過傳遞標誌的最後一個方法結束鏈使用:

V(3).add(7).sub(5, true) // 5 

雖然這工作得很好,它需要一些代碼重複,並使鏈接更不可讀,我的代碼不那麼優雅。

2:使用start()和end()方法

_chain = false; 
function V(p) { 
    function Wrap(w) { 
    return (_chain) ? V(w) : w; 
    } 
    return { 
    add : function(addend) { return Wrap(p + addend); }, 
    sub : function(subtra) { return Wrap(p - subtra); }, 
    start : function() { _chain = true; }, 
    end : function() { _chain = false; return p; } 
    }; 
} 

使用這種方法,你可以做單一的操作,沒有更多的代碼:

V(3).add(7) // 10 

但鏈接需要兩個以上的方法,使事情變得更不可讀:

V(3).start().add(7).sub(5).end() // 5 

所以基本上我只是尋找實現鏈接到我的圖書館的最佳方式。理想情況下,我正在尋找可以使用任意數量方法的東西,而不需要以不雅的方式終止鏈條。

V(3).add(7).sub(5) // 5, perfect chaining 
+1

我建議看看jQuery實施鏈接的方式。 – 2011-03-20 18:48:14

+1

你會發現'underscore.js'實現你的第二個與[.chain](http://documentcloud.github.com/underscore/#chain) – Raynos 2011-03-20 18:55:31

回答

11

爲什麼不引入私人變量,並就這一工作?我想這更加方便。另外,有一個純粹的「getter」最終返回計算的值可能是一個好主意。這可能是這樣的:

function V(p) { 
    var value = p; 

    return { 
     add : function(addend) { value += addend; return this; }, 
     sub : function(subtra) { value -= subtra; return this; }, 
     get : function() { return value; } 
    }; 
} 

V(5).add(7).sub(5).get(); // 5 

你不能在getter函數返回Object明顯。所以你需要一些鏈接結束並返回值的方法。

+0

嗯,我想這將工作。絕對是迄今爲止我見過的最好的提案。 – 2011-03-20 18:44:09

+1

我不認爲這真的有效。你設置p而不是價值。應該返回7 – 2011-03-20 18:46:31

+0

@nathan gonzales:我的不好,修正了錯字。 – jAndy 2011-03-20 18:48:45

6

在某些情況下,它確實需要類似於end,但在您的簡單算術示例中,它不會。

function V(initial_val){ 
    if(!(this instanceof V)){ 
    return new V(initial_val); 
    } 

    var num = initial_val || 0; 

    this.set = function(val){ 
    num = val; 
    return this; 
    } 
    this.add = function(val){ 
    num += val; 
    return this; 
    } 
    this.sub = function(val){ 
    num -= val; 
    return this; 
    } 
    this.valueOf = function(){ 
    return num; 
    } 
    this.toString = function(){ 
    return ""+num; 
    } 
} 

通過添加valueOftoString功能的對象,你可以訪問其原始值。也就是說,你可以這樣做:

var num = V(0).add(1).sub(2), another_num = 3 + num; // num = -1 and another_num = 2; 
2

我將修訂豪馳的出色答卷如下:

使用原型將是,如果你有在ToString函數我調用許多V對象和 更高效通用數字toString與任何 參數您關心給它。

function V (n) { 
    if (!(this instanceof V)) { 
    return new V (n); 
    } 

    this.num = +n || 0; 
    return this; 
} 

V.prototype = { 
    set: function (val) { 
    this.num = val; 
    return this; 
    }, 
    add: function (val) { 
    this.num += val; 
    return this; 
    }, 
    sub: function (val) { 
    this.num -= val; 
    return this; 
    }, 
    valueOf: function() { 
    return this.num; 
    }, 
    toString: function() { 
    return this.num.toString.apply (this.num, arguments); 
    } 
} 
相關問題