是否可以在 JavaScript 中创建自定义运算符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20728460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to create custom operators in JavaScript?
提问by Ionic? Biz?u
During the Math classes we learned how to define new operators. For example:
在数学课上,我们学习了如何定义新的运算符。例如:
(?, °), x ° y = x + 2y
(?, °), x ° y = x + 2y
This defines °
law. For any real numbers xand y, x ° yis x + 2y.
这定义了°
法律。对于任何实数x和y,x ° y是x + 2y。
Example: 2 ° 2 = 2 + 4 = 6
.
例子:2 ° 2 = 2 + 4 = 6
。
Is possible to define operators like this in JavaScript? I know that a function would do the job:
可以在 JavaScript 中定义这样的运算符吗?我知道一个函数可以完成这项工作:
function foo (x, y) { return x + 2 * y; }
but I would like to have the following syntax:
但我想要以下语法:
var y = 2 ° 2; // returns 6
instead of this:
而不是这个:
var y = foo(2, 2);
Which is the closest solution to this question?
哪个是最接近这个问题的解决方案?
采纳答案by Benjamin Gruenbaum
The short answer is no. ECMAScript (the standard JS is based on) does not support operator overloading.
最简洁的答案是不。ECMAScript(标准 JS 所基于的)不支持运算符重载。
As an aside, in ECMAScript 7, you'll be able to overload a subset of the standard operators when designing custom value types. Here is a slide deck by language creator and Mozilla CTO Brendan Eichabout the subject. This won't allow arbitary operators, however, and the overloaded meaning will only be applied to value types.<- haha that ended up not happening.
顺便说一句,在 ECMAScript 7 中,您将能够在设计自定义值类型时重载标准运算符的子集。这是语言创建者和 Mozilla 首席技术官 Brendan Eich关于这个主题的幻灯片。但是,这将不允许任意运算符,并且重载的含义仅适用于值类型。<-哈哈,结果没有发生。
It is possible to use third party tools like sweet.jsto add custom operators though that'd require an extra compilation step.
可以使用诸如sweet.js 之类的第三方工具来添加自定义运算符,但这需要额外的编译步骤。
I've answered with a solution from outside JavaScriptusing esprima - this is changingJavaScript and extending it, it's not native.
我已经使用 esprima从外部 JavaScript 中回答了一个解决方案- 这正在改变JavaScript 并扩展它,它不是原生的。
回答by Joseph
No. You can't do that in JS.
不。你不能在 JS 中做到这一点。
The closest you can have IMO is to implement your ownobject which has a chainable interface, aka "fluent" syntax. That way you can operate as if you were speaking out in sequence.
您可以拥有 IMO 的最接近的方法是实现您自己的对象,该对象具有可链接的接口,也就是“流畅”语法。这样你就可以像按顺序说话一样操作。
var eq = new YourEquationObject();
// Then operate like 1 - 2 * 3
eq.add(1).sub(2).mul(3);
Details are up to you though. Just giving out an idea.
细节取决于你。只是给出一个想法。
回答by Azade
No. JavaScript does not support operator overloading . but you can make a class method for doing this
不可以。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
回答by Eric
You can add pseudo-operators via methods on Number.prototype
:
您可以通过以下方法添加伪运算符Number.prototype
:
Object.defineProperty(Number.prototype, 'myOp', {
value: function(that) {
return this + 2 * that;
}
});
Then all of this syntax will work
然后所有这些语法都将起作用
alert( (2).myOp(2) )
alert( 2 .myOp(2) )
alert( 2..myOp(2) )
alert( 2.0.myOp(2) )
2.myOp(2)
does not work because the period is treated as a decimal point
2.myOp(2)
不起作用,因为句点被视为小数点
回答by ambientlight
Set of compiled to JS languages support custom operators.
一组编译为 JS 语言的支持自定义运算符。
I would highlight ReasonML(ocaml-syntax-readable-by-js-folks) and Bucklescript(ocaml-to-js-compiler) which makes custom operators look neat:
我要强调ReasonML(ocaml-syntax-readable-by-js-folks) 和Bucklescript(ocaml-to-js-compiler),这让自定义操作符看起来很整洁:
For example an operator to concatenate strings can look like:
例如,连接字符串的运算符可能如下所示:
let (>|<) = (list, seperator) => Belt.List.reduce(list, "", (a, b) => a ++ seperator ++ b);
which can then be used like:
然后可以像这样使用:
[Styles.button, Media.Classes.atLeastTablet] >|< " "
The downside of all this is the fact it has to be written in such compiled-to-js language, and it comes with lots of pros and cons, but usually those languages have the appeal of tons of nice syntactic sugar you don't get in js/ts
所有这些的缺点是它必须用这种编译为 js 的语言编写,并且它有很多优点和缺点,但通常这些语言具有你没有得到的大量漂亮的语法糖的吸引力在 js/ts
回答by jpierson
Given the somewhat new tagged template literals feature that was added in ES6 one can create custom DSLs to handle embedded expressions such as these including different algebraic symbols.
鉴于 ES6 中添加的一些新标记模板文字功能,人们可以创建自定义 DSL 来处理嵌入式表达式,例如包括不同代数符号的表达式。
ex. (run in stackblitz)
前任。(在stackblitz 中运行)
function math(strings, x, y) {
// NOTE: Naive approach as demonstration
const operator = strings[1].replace(/\s/gi, "");
if (operator == "°") {
return x + 2 * y;
}
else if (operator == "^") {
return Math.pow(x, y);
}
else {
return `Unknown operator '${operator}'`;
}
}
console.log(math` ° `)
Note that since tagged template literals don't necessarily return strings as results they can return more complex intermediate AST like structures to build up an expression that can then be further refined and then interpreted while keeping close to the domain specific language at hand. I haven't found any existing library that does this yet for Javascript but it should be an interesting and quite approachable endeavor from what it appears from what I know of tagged template literals and usage in such places as lit-html.
请注意,由于标记的模板文字不一定返回字符串作为结果,因此它们可以返回更复杂的中间 AST 之类的结构来构建表达式,然后可以进一步细化并解释该表达式,同时保持接近于手头的特定领域语言。我还没有找到任何现有的库可以为 Javascript 做到这一点,但从我所知道的标记模板文字和在 lit-html 等地方的使用来看,它应该是一个有趣且非常平易近人的努力。
回答by leaf
Read the comments below the answer.
阅读答案下方的评论。
Apparently you can't. Here is something close :
显然你不能。这是接近的事情:
function exec(input) {
return Function(
'return ' + input.replace(/°( *[\d.]+)/g, '+ 2 * ') + ';'
)();
}
exec('2 ° 2'); // 6
回答by krs
The slightly longer then the short one is that Yes you can, but its a bit more involved then what you did in Math class
比短的稍长的是是的,你可以,但它比你在数学课上做的更复杂
To extend the language with new constructs you can use a transformer like http://esprima.org/or any of the others. You need to define your syntax, write the parser to parse your statement and finally add the actual code to do the math parts. When these parts is in place you have made a new language that works just as javascript but with the added support of the °
operator.
要使用新结构扩展语言,您可以使用像http://esprima.org/或任何其他转换器这样的转换器。你需要定义你的语法,编写解析器来解析你的语句,最后添加实际代码来完成数学部分。当这些部分就位时,您就创建了一种新语言,它的工作方式与 javascript 一样,但增加了°
运算符的支持。
Its really not thathard to add new syntax, here is facebooks example how they add => arrow function syntax
它真的不认为很难增加新的语法,这里是Facebook的例子,他们怎么加=>箭头函数语法
https://github.com/facebook/jstransform/blob/master/visitors/es6-arrow-function-visitors.js
https://github.com/facebook/jstransform/blob/master/visitors/es6-arrow-function-visitors.js
回答by Jangofett2008
I was asking this question too, and here's my answer:
我也在问这个问题,下面是我的答案:
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]);