问题出在标题上,但首先请看一下这段代码:
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());
我的问题是,我必须重新调用一个对象以保持函数可链接.我想模仿链规则,但要返回具体的价值.例如,数字(2).add(3)将返回5.
任何建议都非常感谢.
谢谢大家先进.
[X]
解决方法
制作像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
这就是为什么我们需要一个数字(在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 } }
然后,新数字(2)和数字(2)都将评估为新的数字对象.
number(2).value // 2 new number(2).value // 2 number(2) instanceof number // true new number(2) instanceof number // true
快乐的编码.