He estado trabajando con JavaScript durante unos días y he llegado a un punto en el que quiero sobrecargar operadores para mis objetos definidos.
Después de una temporada en Google buscando esto, parece que no puede hacer esto oficialmente, sin embargo, hay algunas personas que afirman una forma larga de realizar esta acción.
Básicamente, hice una clase Vector2 y quiero poder hacer lo siguiente:
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.
En cambio, tengo que hacer esto:
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.
¿Existe algún enfoque que pueda adoptar para sobrecargar operadores en mi clase Vector2? Como esto simplemente se ve feo.
javascript
operators
operator-overloading
Lee Brindley
fuente
fuente
Respuestas:
Como ha descubierto, JavaScript no admite la sobrecarga de operadores. Lo más cerca que puede llegar es implementar
toString
(que se llamará cuando la instancia deba ser forzada a ser una cadena) yvalueOf
(que se llamará para forzarla a un número, por ejemplo, cuando se usa+
para sumar, o en muchos casos cuando usándolo para la concatenación porque+
intenta hacer una suma antes de la concatenación), que es bastante limitado. Ninguno te permite crear unVector2
objeto como resultado.Sin
Vector2
embargo, para las personas que responden a esta pregunta y quieren una cadena o un número como resultado (en lugar de una ), aquí hay ejemplos devalueOf
ytoString
. Estos ejemplos no demuestran la sobrecarga de operadores, solo aprovechan el manejo integrado de JavaScript para convertir a primitivas:valueOf
Este ejemplo duplica el valor de la
val
propiedad de un objeto en respuesta a ser coaccionado a una primitiva, por ejemplo a través de+
:Mostrar fragmento de código
O con ES2015's
class
:Mostrar fragmento de código
O simplemente con objetos, sin constructores:
Mostrar fragmento de código
toString
Este ejemplo convierte el valor de la
val
propiedad de un objeto a mayúsculas en respuesta a ser coaccionado a una primitiva, por ejemplo a través de+
:Mostrar fragmento de código
O con ES2015's
class
:Mostrar fragmento de código
O simplemente con objetos, sin constructores:
Mostrar fragmento de código
fuente
Date
clase convierten implícitamente las fechas en números usandovalueOf
? Por ejemplo, puede hacerlodate2 > date1
y será cierto sidate2
se creó despuésdate1
.>
,<
,>=
, Y<=
(pero no==
,===
,!=
, o!==
) utilizar el Resumen Relational Comparación operación, que utilizaToPrimitive
con "número" pista. En unDate
objeto, eso da como resultado el número quegetTime
devuelve (el valor de milisegundos desde la época).Como dijo TJ, no puede sobrecargar operadores en JavaScript. Sin embargo, puede aprovechar la
valueOf
función para escribir un truco que se ve mejor que usar funciones comoadd
siempre, pero impone las restricciones en el vector de que xey están entre 0 y MAX_VALUE. Aquí está el código:Entonces puedes escribir ecuaciones como esta:
fuente
add
método del OP ... Algo que no querían hacer.+
signo. Esta es una muy buena respuesta que muestra cómo evitar llamar a un nombre de función no natural para objetos cuasi numéricos.+
operador es la capacidad de devolver unNumber
como reemplazo de uno de los operandos. Por lo tanto, cualquier funcionalidad de adición que funcione conObject
instancias siempre debe codificar el objeto como aNumber
y, finalmente, decodificarlo.FYI paper.js resuelve este problema mediante la creación de PaperScript, un javascript autónomo y de alcance con una sobrecarga de vectores de operador, que luego procesa de nuevo en javascript.
Pero los archivos de paperscript deben especificarse y procesarse específicamente como tales.
fuente
En realidad, hay una variante de JavaScript que hace la sobrecarga de operadores de soporte. ExtendScript, el lenguaje de secuencias de comandos utilizado por aplicaciones de Adobe como Photoshop e Illustrator, tiene una sobrecarga de operadores. En él, puedes escribir:
Esto se describe con más detalle en la "Guía de herramientas de JavaScript Extendscript de Adobe" ( enlace actual aquí ). La sintaxis aparentemente se basó en un borrador (ahora abandonado) del estándar ECMAScript.
fuente
Es posible hacer matemáticas vectoriales con dos números empaquetados en uno. Permítanme mostrarles un ejemplo antes de explicar cómo funciona:
Estoy usando el hecho de que si cambias dos números X veces y luego los sumas o restas antes de cambiarlos, obtendrás el mismo resultado que si no los hubieras cambiado al principio. De manera similar, la multiplicación y división escalar funciona simétricamente para valores desplazados.
Un número de JavaScript tiene 52 bits de precisión entera (flotantes de 64 bits), por lo que empaquetaré un número en los 26 bits disponibles más altos y uno en los más bajos. El código se complica un poco más porque quería admitir números firmados.
El único inconveniente que puedo ver con esto es que xey deben estar en el rango + -33 millones, ya que deben caber dentro de 26 bits cada uno.
fuente
Si bien no es una respuesta exacta a la pregunta, es posible implementar algunos de los métodos __magic__ de python utilizando los símbolos ES6
Un
[Symbol.toPrimitive]()
método no le permite implicar una llamadaVector.add()
, pero le permitirá usar una sintaxis comoDecimal() + int
.fuente
También es interesante el operador de biblioteca experimental -overloading-js . Realiza la sobrecarga en un contexto definido (función de devolución de llamada) únicamente.
fuente
Podemos usar Hooks similares a React para evaluar la función de flecha con diferentes valores del
valueOf
método en cada iteración.Mostrar fragmento de código
Library @ js-basics / vector usa la misma idea para Vector3.
fuente