Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript链规则,返回特定值而不是[Object][x]_Javascript_Return Value_Simulation_Chain - Fatal编程技术网

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

Javascript链规则,返回特定值而不是[Object][x],javascript,return-value,simulation,chain,Javascript,Return Value,Simulation,Chain,问题在标题处,但首先请看以下代码: function number(a) { return { add: function(b) { result = a + b; return this; }, substract(b) { result = a - b; return this; } } 上面这些代码是链式规则的简单示例。我重新运行一个对象

问题在标题处,但首先请看以下代码:

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] 您有两个选择。您可以返回新对象:

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);
    }
};
或者您可以修改现有的代码(大部分代码与上面相同,这是不同的):

区别在于它们的行为方式:

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

使数字值如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.
之后需要一个数字(或“nothing”)。因为这是一个全球性的副作用(它会影响所有的数字),所以应该注意避免意外的互动

使“5”链能够运行的另一种方法是创建一个新的
Number
对象(5不是实数实例,即使它使用Number.prototype!),然后复制所需的方法。(我过去认为这是唯一的另一种方法,但请看KooiInc的答案——然而,我不确定从
返回非字符串到字符串
的定义有多明确。)

但是,请记住,这会带来一些微妙的问题:

typeof 5                        // number
typeof new Number(5)            // object
5 instanceof Number             // false
new Number(5) instanceof Number // true
这就是为什么我们需要一个
数字
(在JavaScript中搜索“原语”):

此外,结合cwolves的回答,考虑:

function number (n) { 
  if (this === window) { // or perhaps !(this instanceof number)
    return new number(n)
  } else {
    this.value = n
  }
}
然后,新编号(2)
和编号(2)
都将计算为新编号对象

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

快乐编码。

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

嗨,克沃尔夫斯。现在可以了。但是我想知道是否有其他方法可以链接函数(比如jQuery)并返回特定值而不创建新对象?我的意思是
x=数字(2)。添加(2)。添加(3)
而不是
x=新数字(2);x、 添加(2)。添加(3)
?[x] @xx3004-从构造函数中做出返回语句:
返回这个instanceof number?本:新编号(a)。将样本修改为reflect@cwolves我会将检查移到函数的顶部,以避免在“非新”情况下重复工作(即使在本例中它非常简单)。它还避免了在单个尾随三元条件中“隐藏”意图:)@cwolves Ahh正在查看注释,而不是更新的代码。我只是觉得更新后的代码“太聪明了”:@pst-以前有人批评我使用逗号:)不管怎样,我的观点是正确的。如果构造函数实际上很复杂,那么将
If(!this instanceof number){return new number(a);}
放在构造函数的顶部+1(上面应该显示的
number(5)+3
,结果是8——至少在Firefox4中是这样)。您知道从
toString
返回非字符串是否/在何处定义良好吗?根据我的示例,应该使用valueOf而不是toString:)@all:实际上,仅仅
valueOf
不起作用,但您可以强制
toString
使用
valueOf
-请参阅我的编辑。这是一篇关于对象到原语转换的好文章:这篇文章正如我所期望的那样完美,但我仍然不明白为什么toString:This.valueOf这行太重要了?我甚至没看到你叫它,那它是干什么的?[x] @xx3004链接文章很好。出于某种原因,我认为那些(转换函数)只是内部定义的。。。我真傻。这一个工作正常,但有点复杂。我认为这是一个方便的方法,我从这个例子中学到了很多。我这里有点混乱,行
res.add=op.add
是否将add方法从ops(number)复制到res.add,然后返回?如果你这样做了,如果你有不止一种方法来链接会发生什么?[x] @xx3004许多框架都提供了一种方法,可以同时复制一组属性。(因为执行
res.add=op.add;res.subtract=op.subtract
等操作非常繁琐:-)但是,在该示例中,请注意,每次调用
op
时,都会创建一组新的函数。虽然这可能不是一个问题,但与使用原型的方法相比,这会在闭包中创建更多的垃圾和数据绑定。
function number (n) { 
  if (this === window) { // or perhaps !(this instanceof number)
    return new number(n)
  } else {
    this.value = n
  }
}
number(2).value     // 2
new number(2).value // 2
number(2) instanceof number     // true
new number(2) instanceof number // true
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