6

質問はタイトルにありますが、まずこのコードを見てください:

function number(a) {
    return {
        add: function(b) {
            result = a + b;
            return this;
        }, substract(b) {
            result = a - b;
            return this;
        }
}

上記のこれらのコードは、チェーン ルールの簡単な例です。オブジェクトを返すので、継続的に実行できます。

number(2).add(5).add(3 * 12).substract(Math.random());

私の問題は、関数を連鎖可能に保つためにオブジェクトを返さなければならないことです。チェーンルールを模倣したいのですが、特定の値を返したいです。たとえば、number(2).add(3)5 が返されます。

どんな提案でも大歓迎です。

上級者の皆様、ありがとうございました。[バツ]

4

3 に答える 3

6

5のような数値を「連鎖可能」にする1つの方法は、などの適切なプロトタイプオブジェクトにメソッドを定義することNumber.prototypeです。例えば:

Number.prototype.add = function (n) {
   return this + n
}

(5).add(2) // 7
5.0.add(2) // 7
5..add(2)  // 7
((5).add(2) + 1).add(34) // okay! 42

上記の構文5.add(2)は無効であるためおかしいです。JavaScriptは。の後に数字(または「何もない」)を期待しています5.これはグローバルな副作用であるため(すべての数値に影響します)、予期しない相互作用を回避するように注意する必要があります。

他の唯一の「5」をチェーン可能にする別の方法は、新しいNumberオブジェクトを作成し(Number.prototypeを使用している場合でも5は実際のNumberインスタンスではありません!)、必要なメソッドをコピーすることです。(以前はこれが唯一の方法だと思っていましたが、KooiIncの回答を参照してください。ただし、から非文字列を返すことがどれほど明確に定義されているかはわかりませんtoString。)

function ops(a) {
  return {
    add: function(b) {
      var res = new Number(a + b) // important!
      var op = ops(res)
      res.add = op.add // copy over singletons
      return res
    }
  }
}
function number(a) {
  return ops(a)
}

number(5).add(2) + 1           // 8
(number(5).add(2) + 1).add(34) // error! add is not a function

ただし、これにより微妙な問題が発生することに注意してください。

typeof 5                        // number
typeof new Number(5)            // object
5 instanceof Number             // false
new Number(5) instanceof Number // true

そして、これが私たちが必要とする理由ですNumber(JavaScriptで「プリミティブ」をSOで検索してください):

x = 5
x.foo = "bar"
x.foo // undefined

さらに、cwolvesの回答と併せて、次のことを考慮してください。

function number (n) { 
  if (this === window) { // or perhaps !(this instanceof number)
    return new number(n)
  } else {
    this.value = n
  }
}

次に、両方new number(2)と両方が新しい数値オブジェクトnumber(2)に評価されます。

number(2).value     // 2
new number(2).value // 2
number(2) instanceof number     // true
new number(2) instanceof number // true

ハッピーコーディング。

于 2011-06-26T07:07:06.837 に答える
3

2 つのオプションがあります。新しいオブジェクトを返すことができます:

function number(a){
    return this instanceof number ? (this.value = a, this) : new number(a);
}

number.prototype = {
    valueOf : function(){
        return this.value;
    },
    add : function(b){
        return new number(this.val + b);
    },
    subtract : function(b){
        return new number(this.val - b);
    }
};

または、既存のものを変更することもできます (ほとんど上記と同じコードですが、これは異なります)。

add : function(b){
    this.value += b;
    return this;
},

違いは、それらがどのように動作するかです。

var x = new number(5),
    y = x.add(10);

// with first example
// x == 5, y == 15


// with 2nd example
// x == 15, y == 15, x === y
于 2011-06-26T05:36:07.323 に答える
3

値をプロパティ ( this.a)として定義しtoString、返されたオブジェクト内で使用する場合、メソッドをチェーンできます。

function number(a) {
    return {
        a: Number(a) || 0, //if not a, or a===NaN, default = 0
        add: function(b) {
            this.a += b;
            return this;
        },
        subtract: function(b){
            this.a -= b;
            return this;
        },
        valueOf: function(){
          return Number(this.a);
        },
        toString: this.valueOf
    }
}

var n = number(5);
alert(number.add(5).add(2).subtract(2)); //=> 10
alert(number.add(0.5));                  //=> 10.5
alert(number(2).add(5).add(3 * 12).subtract(Math.random());
                                         //=> 42.36072297706966
于 2011-06-26T08:39:20.410 に答える