Javascript 使Rational类能够处理数学运算符
我有一个Rational类,它对每个操作都有一个方法(add、mult等)Javascript 使Rational类能够处理数学运算符,javascript,operator-overloading,dsl,prototypal-inheritance,fractions,Javascript,Operator Overloading,Dsl,Prototypal Inheritance,Fractions,我有一个Rational类,它对每个操作都有一个方法(add、mult等) 我是否可以使其更“自然”,例如启用控制台.log(a*b)?您不能重载运算符(读取) 此外,像mult这样的专用方法可以被视为良好设计的标志(不仅在Javascript中),因为更改原始操作符行为可能会让用户感到困惑(好吧,一个有理数实际上是重载的一个很好的候选者) 您可以根据用户的建议将print更改为toString 更进一步说: Rational.prototype = { mult : ... ,
我是否可以使其更“自然”,例如启用
控制台.log(a*b)
?您不能重载运算符(读取)
此外,像mult
这样的专用方法可以被视为良好设计的标志(不仅在Javascript中),因为更改原始操作符行为可能会让用户感到困惑(好吧,一个有理数实际上是重载的一个很好的候选者)
您可以根据用户的建议将print
更改为toString
更进一步说:
Rational.prototype = {
mult : ... ,
toString: ... ,
valueOf: function() { return this.nominator / this.denominator; }
};
这将启用
a*b
语法(注意:您不再对理性进行操作,而是对原语进行操作)。作为一个想法,您可以尝试自己编写一个解析器,因此您可以编写如下内容:
console.log(R("a * b"));
其中R是将a*b转换为a.mult(b)的函数,然后对其进行求值。最接近的是某种运算符别名,例如:
/* 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]
参考资料
Javascript不支持运算符重载。不过,你可以用toString
替换print()
。一些形式的求值和字符串替换会起作用,例如:console.log(函数(“a*b.replace”(“*b”),“.mult(b.print()”))关于宏有一些或一些问题可能会有所帮助。这也是我所想的,但结果是错误的:尝试new Rational(1,3).toString()
。不,它没有。如果定义valueOf,字符串转换将使用该值,而不是toString。所以你得到的是0.3333
,而不是1/3
。我专门问了一个关于这个问题的问题。@thg435啊,现在我明白你的意思了。是,当valueOf
返回原语时,可能不会调用toString
,因此0.3333
。但是toString
(在我的回答中)的情况是在显式调用中替换print
/* 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]