簡體   English   中英

在庫中實現Javascript鏈接的最佳方法

[英]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;
  }
}

通過將valueOftoString函數添加到對象,您可以訪問其原始值。 也就是說,你可以這樣做:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM