Javascript链式规则,返回特定值而不是[Object对象] [x]

发布于 2024-11-16 23:34:09 字数 517 浏览 7 评论 0原文

问题在标题上,但首先请看一下这段代码:

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。

任何建议都将受到高度赞赏。

提前感谢大家。 [x]

The question is at the title, but first please look at this code:

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

These code above are simple example of chain rule. I retun an object so I can do it continuously:

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

My problem is, I have to retun an object to keep the function chainable. I'd like to immitate the chain rule, but to return specific value. For instance number(2).add(3) would return 5.

Any suggestion is highly appreciated.

Thanks everyone in advanced.
[x]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

渡你暖光 2024-11-23 23:34:10

使像 5 这样的数值“可链接”的一种方法是在适当的原型对象上定义一个方法,例如 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 对象(5 不是真正的 Number 实例,即使它使用 Number.prototype !)然后复制所需的方法。 (我曾经认为这是唯一的其他方法,但是请参阅 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 中搜索“primitives”):

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

快乐编码。

One way to make a numeric value like 5 "chainable" is to define a method on the appropriate prototype object, such as Number.prototype. For instance:

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

The syntax above is funny because 5.add(2) is invalid: JavaScript is expecting a number (or "nothing") after 5.. Because this is a global side-effect (it will affect all numbers), care should be taken to avoid unexpected interactions.

The only other Another way to make "5" chain-able is to create a new Number object (5 is not a real Number instance, even though it uses Number.prototype!) and then copy over required methods. (I used to think this was the only other way, but see KooiInc's answer -- however, I am not sure how well-defined returning a non-string from toString is.)

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

However, keep in mind this introduces subtle issues:

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

And this is why we need a Number (search SO for "primitives" in JavaScript):

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

Furthermore, in conjunction with cwolves' answer, consider:

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

Then both new number(2) and both number(2) will evaluate to a new number object.

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

Happy coding.

药祭#氼 2024-11-23 23:34:10

你有两个选择。你可以返回新的对象:

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

You have two options. You can return new objects:

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);
    }
};

or you can modify the existing one (mostly the same code as above, this is different):

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

The difference is in how they act:

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
狠疯拽 2024-11-23 23:34:10

如果将值定义为属性 (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

If you define the value as property (this.a) and use toString within the returned Object, you can chain the methods:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文