我可以创建一个隐式输入数字的javascript对象吗?

时间:2011-06-19 09:52:51

标签: javascript oop casting

我想创建一个具有多个公共变量和方法的类,但在应用算术运算符时表现为数字。例如:

 
            a = new hyperNum(4)
            a.func(4)
            a.assign(2.0)
            alert(a + 1.0) `//3.0`

我知道我可以重载Number对象但是我认为所有数字都会有一定的开销。 当我尝试从Number继承时,我收到一个错误:


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)

*/


编辑:

 hyperNum.prototype.valueOf = function(){return this.q;}
成功了。

然而,使用不同的对象或仅扩展Number对象仍然更好吗?

2 个答案:

答案 0 :(得分:4)

您可以实施valueOf,无需延长Number即可:

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"

Live example

答案 1 :(得分:1)

此构造函数始终返回Number。如果它的输入无法转换为数字,那么它的值将为0.这是你想到的吗?

根据评论

[编辑]:Num现在只能接收数字

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