能否实现如下的计算

js中array与+-*/在一起的时候都是先转换为了string,能否覆盖默认的规则,实现下面的效果

[1,2]+[3,4] 结果[4,6]
[1,2]+3 结果 [4,5]
2*[1,2] 结果 [2,4]

当然add([1,2],[3,4])等函数是可以出结果,但数学表达式比较复杂时候,写起来就太别扭了。
如果不可以实现,能否有比较优雅的方式进行数学运算?

阅读 3.6k
3 个回答

你说的这个特性叫做『运算符重载』,这个特性在其他语言比如C++,C#,swift等都比较常见,目前版本的ECMAScript规范和现存的JS实现都没有这个特性,不过未来的ES7有这个草案,可能会在未来加上ES规范中。

以下是ES7一份草案对重载运算符的设想

javascriptFunction.defineOperator("+",function(a,b){
    return a.map((i,v)=>a[i]+b[i]);
},Array,Array); // 这里对应你的第一个例子
Function.defineOperator("+",function(a,b){
    return a.map(v=>v+b);
},Array,Number); // 这里对应你第二个的例子
Function.defineOperator("*",function(a,b){
    return b.map(v=>a*v);
},Number,Array); // 这里对应你第三个的例子

重载好上面的运算符以后就可以使用了,也就是你要的效果。

javascript[1,2]+[3,4] ===》 [4,6]
[1,2]+3 ===》 [4,5]
2*[1,2] ===》 [2,4]

上面只是一个草案的设计,并不代表ES7里一定会这样,而且ES7什么时候能够出稿子也很难说的准,所以目前来说依旧是无解的。
如果题主只是为了写的更清楚的话,而且只对Array和Number进行重载的话,可以在这两个里面的原型上增加函数(不少人对此比较反感),比如 + - * / 对应add, subtract, multiply, divide,那么本来是这样的运算

javascript[2,2] * 3 * ([1,2] + [4,6]) - [2,3] * [1,2]
//可以对应
[2,2].multiply(3).multiply([1,2].add([4,6])).subtract([2,3].multiply([1,2]))

可以看到书写的顺序没有变,不过要写的字符量多起来了。
如果你不嫌麻烦的话其实可以写个预编译工具把第一行自动变成第二行。

貌似没有办法做运算发重载,但是可以向Array.prototype中添加方法,实现类似[1, 2].repeat(n)的方法,也算是简化吧。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题