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]
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]
Share Improve this question asked Jun 26, 2011 at 5:32 xx3004xx3004 7782 gold badges11 silver badges20 bronze badges3 Answers
Reset to default 6One 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.
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
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
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743783422a4506220.html
评论列表(0条)