可以在JavaScript中创建自定义运算符吗?

可以在JavaScript中创建自定义运算符吗?,javascript,operators,Javascript,Operators,在数学课上,我们学习了如何定义新的运算符。例如: (ℝ, ∘), x∘ y=x+2y 这定义了∘定律。对于任何实数x和y,x∘ y是x+2y 示例:2∘ 2=2+4=6 可以在JavaScript中定义这样的运算符吗?我知道函数可以完成这项工作: function foo (x, y) { return x + 2 * y; } 但我希望使用以下语法: var y = 2 ∘ 2; // returns 6 与此相反: var y = foo(2, 2); 哪个是这个问题最接近的解决方案

在数学课上,我们学习了如何定义新的运算符。例如:

(ℝ, ∘), x∘ y=x+2y
这定义了
定律。对于任何实数x和y,x∘ y是x+2y

示例:
2∘ 2=2+4=6


可以在JavaScript中定义这样的运算符吗?我知道函数可以完成这项工作:

function foo (x, y) { return x + 2 * y; }
但我希望使用以下语法:

var y = 2 ∘ 2; // returns 6
与此相反:

var y = foo(2, 2);

哪个是这个问题最接近的解决方案?

简短的答案是否定的。ECMAScript(标准JS基于)不支持运算符重载


另一方面,在ECMAScript 7中,在设计自定义值类型时,可以重载标准运算符的子集。下面是一个关于主题的示例。但是,这不允许使用任意运算符,重载的含义将仅应用于值类型。否。在JS中不能这样做

IMO最接近的方法是实现你自己的对象,它有一个可链接的接口,也就是“流畅”语法。这样你就可以像按顺序说话一样操作

var eq = new YourEquationObject();

// Then operate like 1 - 2 * 3
eq.add(1).sub(2).mul(3);

细节由您决定。只是给出一个想法。

否。JavaScript不支持运算符重载。但您可以为此创建一个类方法

var mathClass = function(value){
   this.value = value;
}

mathClass.prototype.toLaw = function(){
   return 2 * this.value;
}

var y = new mathClass(2)
2 + y.toLaw(); //2 + 2 * y

阅读答案下面的评论。

显然你不能。这里有一点很接近:

function exec(input) {
    return Function(
        'return ' + input.replace(/∘( *[\d.]+)/g, '+ 2 * $1') + ';'
    )();
}

exec('2 ∘ 2'); // 6

长一点的比短一点的是你可以,但它比你在数学课上做的要复杂一点

要使用新的结构扩展语言,您可以使用类似于transformer或任何其他结构。您需要定义语法,编写解析器来解析语句,最后添加实际代码来完成数学部分。当这些部分就绪时,您已经创建了一种新的语言,它可以像javascript一样工作,但需要添加对
操作员

添加新语法并不难,下面是facebooks如何添加=>arrow函数语法的示例


您可以通过
Number.prototype上的方法添加伪运算符:

Object.defineProperty(Number.prototype, 'myOp', {
    value: function(that) {
        return this + 2 * that;
    }
});
那么所有这些语法都会起作用

alert( (2).myOp(2) )
alert( 2 .myOp(2) )
alert( 2..myOp(2) )
alert( 2.0.myOp(2) )

2.myOp(2)
不起作用,因为句点被视为小数点

我也在问这个问题,下面是我的答案:

function myCustomOperation(string){
var res = String.fromCharCode(9762);
var thing = string.replace(/☢/g," + 10 + ");
thing=thing.replace(/☣/g," * 2 + ");
thing=thing.replace(/☠/g," / 3 * ");
return [eval(thing),string+" = "+eval(thing)];
};
var thing = myCustomOperation("

3 ☠ 4

");
document.write(thing[1]);

由于ES6中添加了一些新的标记模板文本特性,因此可以创建自定义DSL来处理嵌入式表达式,例如包含不同代数符号的表达式

ex.(磨合)


请注意,由于标记的模板文本不一定返回字符串作为结果,它们可以返回更复杂的类似AST的中间结构来构建表达式,然后可以进一步细化,然后进行解释,同时保持手头的特定于域的语言。我还没有找到任何现有的库可以这样做r Javascript,但从我所知道的标记模板文本和在lit html等地方的使用情况来看,这应该是一个有趣且相当平易近人的尝试。

一组编译为JS的语言支持自定义运算符

我将重点介绍(js人员可以阅读的ocaml语法)和(ocaml到js编译器),这使自定义运算符看起来整洁:

例如,连接字符串的运算符可以如下所示:

let(>| Belt.List.reduce(List,”,(a,b)=>a++分隔符++b);
然后可以像这样使用:

[Styles.button, Media.Classes.atLeastTablet] >|< " "
[Styles.button,Media.Classes.atLeastTablet]>|<“

所有这些的缺点是,它必须用编译成js语言编写,它有很多优点和缺点,但通常这些语言有着js/ts中没有的大量漂亮的语法糖的吸引力使用现有的操作符,但在JavaScript中就是这样。我想说的是,想要定义一个在键盘上没有符号的操作符是一个非常糟糕的主意。不。你不能在JavaScript中这样做。但是,你可以在Haskell中这样做。第一行:
infixl 6∘。第二行:
x∘ y=x+2*y
。从技术上讲,您可以编写自己的词法分析器,并在
块中定义自己的脚本类型名称。这种技术使用得相当广泛。一些著名的示例包括。您可以添加引用吗?在实现之后,我将如何定义这样的运算符?我怀疑ECMAScript的任何版本都不会出现定义新符号运算符的能力——这通常是为haskell之类的语言保留的。我怀疑它只会随运算符一起出现overloading@EricHaskell所做的并不是魔术。在JS中为中缀符号引入反勾号并没有问题:)然而,是的,目前的提案讨论了运算符重载。@BenjaminGruenbaum:当然,这不是魔术,但定义符号运算符是一个滑铁卢,我看不到有人提到建议用户代码可以声明新的值类型
(1+1)∘ (1+1)
会毁了你的生活day@Eric很好的方法,但是
'2∘ 2'
是字符串。我不想成为字符串@イオニカビザウ: 其思想是将脚本标记为
language=“myjavascript”
,然后在runtineTo上使用一个小脚本将代码翻译成原始javascript。要正确地执行此操作,您需要一个类似或的javascript AST库。如果您想添加新的符号运算符,您可能需要稍微调整解析器。您可以更进一步,将它们添加到
Number.prototype
,如我的回答所示
[Styles.button, Media.Classes.atLeastTablet] >|< " "