5

我有这个 Rational 类,每个操作都有一个方法(add、mult 等)

function Rational(nominator, denominator){
    this.nominator = nominator;
    this.denominator = denominator || 1;    
}

Rational.prototype = {
    mult: function(that) {
        return new Rational(
            this.nominator * that.nominator,
            this.denominator * that.denominator
            );
    },
    print: function() {
        return this.nominator + '/' + this.denominator;
    }
};

var a = new Rational(1,2),
    b = new Rational(3);

console.log( a.mult(b).print() ); // 3/2

我可以让它更“自然”,例如启用console.log( a * b )吗?

4

3 回答 3

9

您不能重载运算符(阅读类似问题)。

此外,像这样的专用方法mult可以被视为良好设计的标志(不仅在 Javascript 中),因为更改原始运算符行为可能会使用户感到困惑(嗯,有理数实际上是重载的良好候选者)。

您可以按照用户thg435的建议更改print为。toString

更进一步:

Rational.prototype = {
    mult : ... ,
    toString: ... ,
    valueOf: function() { return this.nominator / this.denominator; }
};

这将启用a * b语法(注意:您不再对原语进行操作Rationals,而是对原语进行操作)。

于 2013-06-14T11:58:54.167 回答
3

您可以获得的最接近的是某种运算符别名,例如:

/* Accepts a symbolic or string operator, returns a function which accepts numbers */
function operator(node)
  {
  //Mapping between string and symbol operators
  var map = {"mod": "%", "mult": "*", "div": "/", "plus": "+", "minus": "-"}

  //Return a function which applies the string or symbol operator to two numbers
  return Function("x,y", "return x" + (map[node] || node) + "y");
  }

// pass "*" to operator; pass 5,7 to returned function
var foo = operator("*")(5,7); 

// pass "plus" to operator; pass 3,2 to returned function
var bar = operator("plus")(3,2);

// pass "mod" to operator; pass 1,0 to returned function 
var baz = operator("mod")(1,0); 

console.log(["foo",foo,"bar",bar,"baz",baz]); //["foo", 35, "bar", 5, "baz", NaN]

参考

于 2013-06-22T01:12:17.533 回答
0

作为一个想法,您可以尝试自己编写一个解析器,这样您就可以编写如下内容:

console.log(R("a * b")); 

其中 R 是将 a * b 转换为 a.mult(b) 然后 eval 的函数。

于 2013-06-14T12:15:07.010 回答