问题出在标题上,但首先请看一下这段代码:
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]
答案 0 :(得分:6)
制作像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中搜索“原语”的原因)的原因:
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
快乐的编码。
答案 1 :(得分:3)
您有两种选择。您可以返回新对象:
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
答案 2 :(得分:3)
如果您将值定义为属性(this.a
)并在返回的Object中使用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