Javascript:运算符重载

我已经使用JavaScript了几天,现在已经到了一个地步,我想重载我的定义对象的操作符。

谷歌search后,似乎你不能正式这样做,但有几个人在那里声称做了这个行动的一个冗长的方式。

基本上我做了一个Vector2类,并希望能够做到以下几点:

var x = new Vector2(10,10); var y = new Vector2(10,10); x += y; //This does not result in x being a vector with 20,20 as its x & y values. 

相反,我必须这样做:

 var x = new Vector2(10,10); var y = new Vector2(10,10); x = x.add(y); //This results in x being a vector with 20,20 as its x & y values. 

我可以采取什么办法来重载Vector2类中的操作符? 这看起来很丑陋。

如您所见,JavaScript不支持运算符重载。 最接近你可以实现toString (当实例需要被强制为一个string时会被调用)和valueOf (它会被调用强制它为一个数字,例如,当使用+添加,或在很多情况下,当它用于连接,因为+试图做连接之前的加法),这是相当有限的。 因此,也不能让你创build一个Vector2对象。


对于这个问题谁想要一个string或数字作为结果(而不是一个Vector2), though, here are examples of valueOf and toString`的Vector2), though, here are examples of 。 这些示例不会演示运算符重载,只是利用JavaScript的内置处理转换为基元:

valueOf

这个例子将对象的val属性的值加倍,以强制转换为基元,例如通过+

 function Thing(val) { this.val = val; } Thing.prototype.valueOf = function() { // Here I'm just doubling it; you'd actually do your longAdd thing return this.val * 2; }; var a = new Thing(1); var b = new Thing(2); console.log(a + b); // 6 (1 * 2 + 2 * 2) 

正如TJ所说,你不能在JavaScript中重载操作符。 然而,你可以利用valueOf函数来编写一个看起来比使用像每次add函数更好的hack,但是对x和y在0和MAX_VALUE之间的向量施加约束。 这里是代码:

 var MAX_VALUE = 1000000; var Vector = function(a, b) { var self = this; //initialize the vector based on parameters if (typeof(b) == "undefined") { //if the b value is not passed in, assume a is the hash of a vector self.y = a % MAX_VALUE; self.x = (a - self.y) / MAX_VALUE; } else { //if b value is passed in, assume the x and the y coordinates are the constructors self.x = a; self.y = b; } //return a hash of the vector this.valueOf = function() { return self.x * MAX_VALUE + self.y; }; }; var V = function(a, b) { return new Vector(a, b); }; 

然后你可以写这样的公式:

 var a = V(1, 2); //a -> [1, 2] var b = V(2, 4); //b -> [2, 4] var c = V((2 * a + b) / 2); //c -> [2, 4] 

FYI paper.js通过创buildPaperScript来解决这个问题,它是一个自包含的范围化的JavaScript,带有运算符向量的重载,然后将其处理回javascript。

但是需要特别指定和处理paperscript文件。

我最喜欢处理vector的方法是创build一个包含vector键的数组,并且每当我需要使用vector的两个组件时循环该数组。 我没有testing这种方法的性能,但是我相信它比stream行的库更有效率,因为它在计算时不会创build任何对象,也不会执行任何function。 而且,它更具可读性。

 function Vector(x, y) { this.x = x; this.y = y; } const comps = ['x', 'y']; var d = new Vector(0, 0); var v = new Vector(10, 0); var t = 1; for(let c of comps) { d[c] += v[c] * t; } console.log(d); //{ x: 10, y: 0 }