[英]Best way to implement Javascript chaining in a library
我正在創建一個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
為什么不引入一個私有變量並進行處理呢? 我想這更方便。 另外,擁有一個最終返回計算值的純“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
。 所以你需要一些鏈接結束並返回值的方法。
在某些情況下,它確實需要具有類似於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;
}
}
通過將valueOf
和toString
函數添加到對象,您可以訪問其原始值。 也就是說,你可以這樣做:
var num = V(0).add(1).sub(2), another_num = 3 + num; // num = -1 and another_num = 2;
我會將Haochi的優秀答案修改如下:
如果你有很多V對象,那么使用原型會更有效率。在toString函數中,我使用你想要的任何參數來調用通用數字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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.