¿Sobrecargar operadores aritméticos en JavaScript?

Resuelto Peter McG asked hace 14 años • 11 respuestas

Esta es la mejor manera que se me ocurre de formular esta pregunta, dada esta definición de "clase" de JavaScript:

var Quota = function(hours, minutes, seconds){
    if (arguments.length === 3) {
        this.hours = hours;
        this.minutes = minutes;
        this.seconds = seconds;

        this.totalMilliseconds = Math.floor((hours * 3600000)) + Math.floor((minutes * 60000)) + Math.floor((seconds * 1000));
    }
    else if (arguments.length === 1) {
        this.totalMilliseconds = hours;

        this.hours = Math.floor(this.totalMilliseconds / 3600000);
        this.minutes = Math.floor((this.totalMilliseconds % 3600000) / 60000);
        this.seconds = Math.floor(((this.totalMilliseconds % 3600000) % 60000) / 1000);
    }

    this.padL = function(val){
        return (val.toString().length === 1) ? "0" + val : val;
    };

    this.toString = function(){
        return this.padL(this.hours) + ":" + this.padL(this.minutes) + ":" + this.padL(this.seconds);
    };

    this.valueOf = function(){
        return this.totalMilliseconds;
    };
};

y el siguiente código de configuración de prueba:

var q1 = new Quota(23, 58, 50);
var q2 = new Quota(0, 1, 0);
var q3 = new Quota(0, 0, 10);

console.log("Quota 01 is " + q1.toString());    // Prints "Quota 01 is 23:58:50"
console.log("Quota 02 is " + q2.toString());    // Prints "Quota 02 is 00:01:00"
console.log("Quota 03 is " + q3.toString());    // Prints "Quota 03 is 00:00:10"

¿Hay alguna forma de crear implícitamente q4como un Quotaobjeto usando el operador de suma de la siguiente manera...

var q4 = q1 + q2 + q3;
console.log("Quota 04 is " + q4.toString());    // Prints "Quota 04 is 86400000"

en lugar de recurrir a...

var q4 = new Quota(q1 + q2 + q3);
console.log("Quota 04 is " + q4.toString());    // Prints "Quota 04 is 24:00:00"

En caso contrario, ¿cuáles son las recomendaciones de mejores prácticas en esta área para hacer que los objetos JavaScript numéricos personalizados se puedan componer a través de operadores aritméticos?

Peter McG avatar Oct 28 '09 06:10 Peter McG
Aceptado

Hasta donde yo sé, Javascript (al menos tal como existe ahora) no admite la sobrecarga de operadores.

Lo mejor que puedo sugerir es un método de clase para crear nuevos objetos de cuota a partir de varios otros. Aquí hay un ejemplo rápido de lo que quiero decir:

// define an example "class"
var NumClass = function(value){
    this.value = value;
}
NumClass.prototype.toInteger = function(){
    return this.value;
}

// Add a static method that creates a new object from several others
NumClass.createFromObjects = function(){
    var newValue = 0;
    for (var i=0; i<arguments.length; i++){
        newValue += arguments[i].toInteger();
    }
    return new this(newValue)
}

y usarlo como:

var n1 = new NumClass(1);
var n2 = new NumClass(2);
var n3 = new NumClass(3);

var combined = NumClass.createFromObjects(n1, n2, n3);
Dan avatar Oct 28 '2009 01:10 Dan

Lamentablemente no.

Para alternativas, si organizó los valores de retorno, podría usar el encadenamiento de métodos

var q4 = q1.plus(p2).plus(q3);
Justin Love avatar Oct 28 '2009 01:10 Justin Love

Paper.js lo hace, por ejemplo con la suma de puntos ( docs ):

var point = new Point(5, 10);
var result = point + 20;
console.log(result); // {x: 25, y: 30}

Pero lo hace utilizando su propio analizador de secuencias de comandos personalizado .

Izhaki avatar Sep 15 '2016 14:09 Izhaki