【问题标题】:Can I create a javascript object that is casted implicitly as number?我可以创建一个隐式转换为数字的 javascript 对象吗?
【发布时间】:2011-06-19 09:52:51
【问题描述】:

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

 
            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 对象更好?

【问题讨论】:

  • 至少在 JavaScript 中没有运算符重载。
  • @pimvdd:不,但是valueOftoString 函数为对象提供了有用的功能...

标签: javascript oop casting


【解决方案1】:

只需实现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

【讨论】:

  • 有时自己实现是最简单的。当我只需要几个函数时,我对 Array 也有同样的痛苦......
【解决方案2】:

这个构造函数总是返回一个数字。如果它的输入不能转换为数字,它的值将是 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

【讨论】:

  • 不完全是,因为构造函数不应该接受字符串,不能转换为数字,应该是错误,而不是静默转换为0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多