Reputation: 532
I want to create a class that has several public variables and methods,but behaves as number when arithmetic operators are applied.Example :
a = new hyperNum(4)
a.func(4)
a.assign(2.0)
alert(a + 1.0) `//3.0`
I know I can just overload the Number object but then I think that there would be a certain overhead for all numbers. When I tried to inherit from Number ,I got an error:
function hyperNum () {}
hyperNum.prototype = new Number();
hyperNum.prototype.z = function(q){this.q = q;}
h = new hyperNum(2);
h+5
/* error:
TypeError: Number.prototype.valueOf is not generic
at Number.valueOf (native)
at Number.ADD (native)
at [object Context]:1:2
at Interface. (repl:96:19)
at Interface.emit (events:31:17)
at Interface._ttyWrite (readline:309:12)
at Interface.write (readline:147:30)
at Stream. (repl:79:9)
at Stream.emit (events:31:17)
at IOWatcher.callback (net:489:16)
*/
EDIT:
hyperNum.prototype.valueOf = function(){return this.q;}
made it.
However still is it better to use a different object or just to extend the Number object?
Upvotes: 2
Views: 732
Reputation: 122906
This constructor always returns a Number. If it's input can't be converted to a Number, it's value will be 0. Is that what you had in mind?
[edit] based on comment: Num
now can only receive numbers
function Num(num){
if (!(this instanceof Num)){
return new Num(num);
}
this.num = setNum(num);
//setNum checks if input is number
function setNum(n){
this.num = n && n.constructor !== Number ? NaN : Number(n);
return this.num;
}
//numChk checks if this.num is a number before returning it
function numChk(){
return isNaN(this.num)
? 'Not a Number!'
: Number(this.num);
}
if (!Num.prototype.ok) {
var proto = Num.prototype;
proto.valueOf = function(){return numChk.call(this);};
proto.toString = Num.prototype.valueOf;
proto.assign = function(val){setNum.call(this,val); return this;};
proto.ok = true;
}
};
// usages
var a = Num(1.0)
, b = Num(23)
, c = Num('0.44')
, d = Num('becomes zero')
;
a + b; //=> 24
a.assign(4.8) + b; //=> 27.8
c + d; //=> 'Not a NumberNot a Number'
a + c; //=> '4.8Not a Number'
b.assign(b%2); //=> 1
c.assign(0.44) //=> 0.44
Upvotes: 1
Reputation: 1074295
You can just implement valueOf
, no need to extend Number
to do it:
function Foo(val) {
this.val = val;
}
Foo.prototype.valueOf = function() {
return this.val;
};
Foo.prototype.toString = function() {
return "Foo: " + this.val;
};
display("f = " + f); // "f = 42"
display("f + 1 = " + (f + 1)); // "f + 1 = 43"
display("f * 2 = " + (f * 2)); // "f * 2 = 84"
display("f as a string = " + String(f)); // "f as a string = Foo: 42"
Upvotes: 4