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

Ion*_*zău 29 javascript operators

在Math类中,我们学习了如何定义新的运算符.例如:

(?, ?), x ? y = x + 2y

这定义了?法律.对于任何实数xy,x∘yx + 2y.

示例:2 ? 2 = 2 + 4 = 6.


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

function foo (x, y) { return x + 2 * y; }
Run Code Online (Sandbox Code Playgroud)

但是我希望有以下语法:

var y = 2 ? 2; // returns 6
Run Code Online (Sandbox Code Playgroud)

而不是这个:

var y = foo(2, 2);
Run Code Online (Sandbox Code Playgroud)

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

Ben*_*aum 21

最简洁的答案是不.ECMAScript(标准JS基于)不支持运算符重载.

另外,在ECMAScript 7中,您可以在设计自定义值类型时重载标准运算符的子集.这是一个由语言创建者和Mozilla CTO Brendan Eich关于这个主题的幻灯片.但是,这不允许任意操作符,并且重载的含义仅适用于值类型.< - 哈哈最终没有发生.

虽然需要额外的编译步骤,但可以使用像sweet.js这样的第三方工具来添加自定义运算符.

我已经使用esprima 回答了来自外部JavaScript的解决方案 - 这正在改变 JavaScript并扩展它,它不是原生的.


jpi*_*son 8

鉴于 ES6 中添加的某种新的标记模板文字功能,我们可以创建自定义 DSL 来处理嵌入式表达式,例如包含不同代数符号的表达式。

\n\n

前任。(在stackblitz中运行)

\n\n
function math(strings, x, y) {\n  // NOTE: Naive approach as demonstration\n\n  const operator = strings[1].replace(/\\s/gi, "");\n\n  if (operator == "\xe2\x88\x98") {\n    return x + 2 * y;\n  }\n  else if (operator == "^") {\n    return Math.pow(x, y);\n  }\n  else {\n    return `Unknown operator \'${operator}\'`;\n  }\n}\n\nconsole.log(math`${2} \xe2\x88\x98 ${2}`)\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n


Jos*_*eph 5

不,在 JS 中你不能这样做。

在我看来,最接近的方法是实现自己的对象,该对象具有可链接的接口,也称为“流利”语法。这样你就可以像按顺序说话一样进行操作。

var eq = new YourEquationObject();

// Then operate like 1 - 2 * 3
eq.add(1).sub(2).mul(3);
Run Code Online (Sandbox Code Playgroud)

不过细节取决于你。只是给出一个想法。


Eri*_*ric 5

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

Object.defineProperty(Number.prototype, 'myOp', {
    value: function(that) {
        return this + 2 * that;
    }
});
Run Code Online (Sandbox Code Playgroud)

然后所有这些语法都将起作用

alert( (2).myOp(2) )
alert( 2 .myOp(2) )
alert( 2..myOp(2) )
alert( 2.0.myOp(2) )
Run Code Online (Sandbox Code Playgroud)

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